From f2ee2569d65ac968fd0369933677167a7a3b583f Mon Sep 17 00:00:00 2001 From: Kateryna Nemesh Date: Mon, 8 Dec 2025 10:53:47 +0100 Subject: [PATCH 01/83] Add draft of FASTQ_REMOVE_ADAPTERS_AND_MERGE subworkflow with tests --- .../fastq_remove_adapters_and_merge/main.nf | 124 ++++++++++++++++++ .../fastq_remove_adapters_and_merge/meta.yml | 51 +++++++ .../tests/main.nf.test | 95 ++++++++++++++ .../tests/main.nf.test.snap | 92 +++++++++++++ .../tests/nextflow.config | 17 +++ 5 files changed, 379 insertions(+) create mode 100644 subworkflows/nf-core/fastq_remove_adapters_and_merge/main.nf create mode 100644 subworkflows/nf-core/fastq_remove_adapters_and_merge/meta.yml create mode 100644 subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test create mode 100644 subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test.snap create mode 100644 subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/nextflow.config diff --git a/subworkflows/nf-core/fastq_remove_adapters_and_merge/main.nf b/subworkflows/nf-core/fastq_remove_adapters_and_merge/main.nf new file mode 100644 index 000000000000..f13df3bef4af --- /dev/null +++ b/subworkflows/nf-core/fastq_remove_adapters_and_merge/main.nf @@ -0,0 +1,124 @@ +// ok for single end adapter removal +include { TRIMMOMATIC } from '../../../modules/nf-core/trimmomatic/main' +include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' +include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' +include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' + +// allows merging of paired end reads, but will work for single end reads as well +include { FASTP } from '../../../modules/nf-core/fastp/main' +include { ADAPTERREMOVAL} from '../../../modules/nf-core/adapterremoval/main' +include { LEEHOM } from '../../../modules/nf-core/leehom/main' + +// requirs paired end becouse of merging +include { NGMERGE } from '../../../modules/nf-core/ngmerge/main' + +workflow FASTQ_REMOVE_ADAPTERS_AND_MERGE { + + take: + reads // (meta, reads) - SE or PE + skip_trimmomatic // boolean + skip_cutadapt + skip_trimgalore + skip_bbduk + skip_fastp + skip_adapterremoval + skip_leehom + skip_ngmerge + do_merge + adapters_contaminants + main: + + ch_current = reads + ch_versions = Channel.empty() + + if (!skip_trimmomatic) { + // TRIMMOMATIC.ext.adapters = adapters_contaminants + TRIMMOMATIC( ch_current ) + ch_current = TRIMMOMATIC.out.trimmed_reads.map { meta, r -> [meta, r] } + ch_versions = ch_versions.mix(TRIMMOMATIC.out.versions) + } + + if (!skip_cutadapt) { + CUTADAPT( ch_current ) + ch_current = CUTADAPT.out.reads.map { meta, r -> [meta, r] } + ch_versions = ch_versions.mix(CUTADAPT.out.versions) + } + + if (!skip_trimgalore) { + TRIMGALORE( ch_current ) + ch_current = TRIMGALORE.out.reads.map { meta, r -> [meta, r] } + ch_versions = ch_versions.mix(TRIMGALORE.out.versions) + } + + if (!skip_bbduk) { + ch_current.view { "DEBUG: BEFORE BBMAP_BBDUK → $it" } + BBMAP_BBDUK( ch_current, adapters_contaminants ) + ch_current = BBMAP_BBDUK.out.reads.map { meta, r -> [meta, r] } + ch_versions = ch_versions.mix(BBMAP_BBDUK.out.versions) + ch_current.view { "DEBUG: AFTER BBMAP_BBDUK → $it" } + } + + if (!skip_fastp && !do_merge) { + ch_current.view { "DEBUG: BEFORE FASTP → $it" } + FASTP( ch_current.map { meta, r -> tuple(meta, r, adapters_contaminants)}, + false, + true, + do_merge) + ch_current = FASTP.out.reads.map { meta, r -> [meta, r] } + ch_versions = ch_versions.mix(FASTP.out.versions) + ch_current.view { "DEBUG: AFTER FASTP → $it" } + } + + if (!skip_adapterremoval && !do_merge) { + ADAPTERREMOVAL( ch_current, adapters_contaminants ) + ch_current.view { "DEBUG: BEFORE ADAPTERREMOVAL → $it" } + ch_current = ADAPTERREMOVAL.out.paired_truncated + .mix(ADAPTERREMOVAL.out.singles_truncated) + .map { tup -> + def meta = tup[0] + def r = tup[1] + [meta, r] + } + ch_versions = ch_versions.mix(ADAPTERREMOVAL.out.versions) + ch_current.view { "DEBUG: AFTER ADAPTERREMOVAL → $it" } + } + + if (!skip_leehom && !do_merge) { + ch_current.view { "DEBUG: BEFORE LEEHOM → $it" } + ch_leehom_input = ch_current.map { meta, r -> + if (meta.single_end) + return [meta, r] + else + return [meta, [reads[0], reads[1]]] + } + + LEEHOM(ch_leehom_input) + + ch_leehom_pe = + LEEHOM.out.unmerged_r1_fq_pass + .combine(LEEHOM.out.unmerged_r2_fq_pass) + .map { left, right -> + def meta = left[0] + def r1 = left[1] + def r2 = right[1] + [meta, [r1, r2]] + } + .filter { meta, r -> !meta.single_end } // only PE + +// ---- SE OUTPUT ---- +ch_leehom_se = + LEEHOM.out.fq_pass + .filter { meta, r -> meta.single_end } + .map { meta, r -> [meta, r] } + +// ---- MERGE CHANNELS ---- +ch_current = ch_leehom_pe.mix(ch_leehom_se) + + ch_versions = ch_versions.mix(LEEHOM.out.versions) + } + + emit: + + trimmed_reads = ch_current // channel: [ meta, trimmed_reads ] + versions = ch_versions // channel: [ versions.yml ] +} diff --git a/subworkflows/nf-core/fastq_remove_adapters_and_merge/meta.yml b/subworkflows/nf-core/fastq_remove_adapters_and_merge/meta.yml new file mode 100644 index 000000000000..0390e17f75c6 --- /dev/null +++ b/subworkflows/nf-core/fastq_remove_adapters_and_merge/meta.yml @@ -0,0 +1,51 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "fastq_remove_adapters_and_merge" +## TODO nf-core: Add a description of the subworkflow and list keywords +description: Sort SAM/BAM/CRAM file +keywords: + - sort + - bam + - sam + - cram +## TODO nf-core: Add a list of the modules and/or subworkflows used in the subworkflow +components: + - samtools/sort + - samtools/index +## TODO nf-core: List all of the channels used as input with a description and their structure +input: + - ch_bam: + type: file + description: | + The input channel containing the BAM/CRAM/SAM files + Structure: [ val(meta), path(bam) ] + pattern: "*.{bam/cram/sam}" +## TODO nf-core: List all of the channels used as output with a descriptions and their structure +output: + - bam: + type: file + description: | + Channel containing BAM files + Structure: [ val(meta), path(bam) ] + pattern: "*.bam" + - bai: + type: file + description: | + Channel containing indexed BAM (BAI) files + Structure: [ val(meta), path(bai) ] + pattern: "*.bai" + - csi: + type: file + description: | + Channel containing CSI files + Structure: [ val(meta), path(csi) ] + pattern: "*.csi" + - versions: + type: file + description: | + File containing software versions + Structure: [ path(versions.yml) ] + pattern: "versions.yml" +authors: + - "@kornkv" +maintainers: + - "@kornkv" diff --git a/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test new file mode 100644 index 000000000000..3ba4c0236b64 --- /dev/null +++ b/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test @@ -0,0 +1,95 @@ +nextflow_workflow { + + name "Test Subworkflow FASTQ_REMOVE_ADAPTERS_AND_MERGE" + script "../main.nf" + workflow "FASTQ_REMOVE_ADAPTERS_AND_MERGE" + + tag "subworkflows" + tag "trimmomatic" + tag "cutadapt" + tag "trimgalore" + tag "bbmap/bbduk" + tag "fastp" + tag "adapterremoval" + tag "leehom" + tag "ngmerge" + + /************************************************************** + * TEST 1 — SINGLE END + **************************************************************/ + test("sarscov2 - fastq - single-end") { + config "./nextflow.config" + when { + workflow { + """ + input[0] = [ + [ id:'test', single_end:true ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ] + + input[1] = false // skip_trimmomatic + input[2] = false // skip_cutadapt + input[3] = false // skip_trimgalore + input[4] = false // skip_bbduk + input[5] = false // skip_fastp + input[6] = false // skip_adapterremoval + input[7] = false // skip_leehom + input[8] = true // skip_ngmerge + input[9] = false // do_merge + input[10] = [] + """ + } + } + + then { + assert workflow.success + + assert snapshot( + workflow.out.trimmed_reads.sort(), + workflow.out.versions.collect { path(it).yaml }.sort() + ).match() + } + } + + + /************************************************************** + * TEST 2 — PAIRED END + **************************************************************/ + test("sarscov2 - fastq - paired-end, no merging") { + config "./nextflow.config" + when { params { + samtools_arg = '' + } + workflow { + """ + input[0] = [ + [ id:'test_paired', single_end:false ], + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ] + + input[1] = false // skip_trimmomatic + input[2] = false // skip_cutadapt + input[3] = false // skip_trimgalore + input[4] = false // skip_bbduk + input[5] = false // skip_fastp + input[6] = false // skip_adapterremoval + input[7] = false // skip_leehom + input[8] = true // skip_ngmerge + input[9] = false // do_merge + input[10] = [] + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + +} diff --git a/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test.snap new file mode 100644 index 000000000000..d66a72a5622e --- /dev/null +++ b/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test.snap @@ -0,0 +1,92 @@ +{ + "sarscov2 - fastq - paired-end, no merging": { + "content": [ + { + "0": [ + + ], + "1": [ + "versions.yml:md5,2d964cf60309a142f1c9958da875eb54", + "versions.yml:md5,90401b38cbb7e43510ca1a7cbcea3145", + "versions.yml:md5,95732be10dd312717626b93c727886ef", + "versions.yml:md5,aa5ed9a565951378f5d671bfa6b88370", + "versions.yml:md5,b9c8e5d6936d4d2dbc08084d03ee57c8", + "versions.yml:md5,de9c9c39a848b9543456f693e4ca6ad3" + ], + "trimmed_reads": [ + + ], + "versions": [ + "versions.yml:md5,2d964cf60309a142f1c9958da875eb54", + "versions.yml:md5,90401b38cbb7e43510ca1a7cbcea3145", + "versions.yml:md5,95732be10dd312717626b93c727886ef", + "versions.yml:md5,aa5ed9a565951378f5d671bfa6b88370", + "versions.yml:md5,b9c8e5d6936d4d2dbc08084d03ee57c8", + "versions.yml:md5,de9c9c39a848b9543456f693e4ca6ad3" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-08T10:34:07.314632994" + }, + "sarscov2 - fastq - single-end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fq.gz:md5,6dcea64429b2bcf5e31751f9c8041914" + ] + ], + [ + { + "FASTQ_REMOVE_ADAPTERS_AND_MERGE:FASTP": { + "fastp": "1.0.1" + } + }, + { + "FASTQ_REMOVE_ADAPTERS_AND_MERGE:TRIMGALORE": { + "trimgalore": "0.6.10", + "cutadapt": 4.9, + "pigz": 2.8 + } + }, + { + "FASTQ_REMOVE_ADAPTERS_AND_MERGE:LEEHOM": { + "leehom": "1.2.15" + } + }, + { + "FASTQ_REMOVE_ADAPTERS_AND_MERGE:ADAPTERREMOVAL": { + "adapterremoval": "2.3.2" + } + }, + { + "FASTQ_REMOVE_ADAPTERS_AND_MERGE:TRIMMOMATIC": { + "trimmomatic": 0.39 + } + }, + { + "FASTQ_REMOVE_ADAPTERS_AND_MERGE:BBMAP_BBDUK": { + "bbmap": 39.18 + } + }, + { + "FASTQ_REMOVE_ADAPTERS_AND_MERGE:CUTADAPT": { + "cutadapt": 5.0 + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-08T10:33:53.838298621" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/nextflow.config b/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/nextflow.config new file mode 100644 index 000000000000..6b7b780d8765 --- /dev/null +++ b/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/nextflow.config @@ -0,0 +1,17 @@ +process { + + withName: TRIMMOMATIC { + ext.args = { + def adapters = "TruSeq3-SE.fa" + "ILLUMINACLIP:${adapters}:2:30:10 LEADING:3 TRAILING:3 SLIDINGWINDOW:4:15 MINLEN:36" + } + } + + withName: CUTADAPT { + ext.args = '-q 25' + } + withName: BBMAP_BBDUK { + ext.args = 'trimq=10 qtrim=r' + ext.prefix = { "${meta.id}.trim" } + } + } From 060b52dda0013a9b2c19cfbb256b215005658428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Mon, 1 Dec 2025 14:51:47 +0100 Subject: [PATCH 02/83] Add ontologies to tcoffee/regressive and upp/align modules (#9484) * add ontologies to tcoffee regressive * add ontologies to upp align --- modules/nf-core/tcoffee/regressive/meta.yml | 20 +++++++++++++------- modules/nf-core/upp/align/meta.yml | 12 +++++++++--- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/modules/nf-core/tcoffee/regressive/meta.yml b/modules/nf-core/tcoffee/regressive/meta.yml index a272190f7e00..fa7a752e6937 100644 --- a/modules/nf-core/tcoffee/regressive/meta.yml +++ b/modules/nf-core/tcoffee/regressive/meta.yml @@ -30,7 +30,9 @@ input: type: file description: Input sequences in FASTA format pattern: "*.{fa,fasta}" - ontologies: [] + ontologies: + - edam: http://edamontology.org/format_1919 # SEQUENCE-LIKE + - edam: http://edamontology.org/format_1929 # FASTA - - meta2: type: map description: | @@ -40,7 +42,8 @@ input: type: file description: Input guide tree in Newick format pattern: "*.{dnd}" - ontologies: [] + ontologies: + - edam: http://edamontology.org/format_2006 # PHYLOGENETIC TREE - - meta3: type: map description: | @@ -50,14 +53,14 @@ input: type: file description: T_coffee template file that maps sequences to the accessory information files to be used. - pattern: "*" - ontologies: [] + ontologies: + - edam: http://edamontology.org/format_1476 # PDB - accessory_information: type: file description: Accessory files to be used in the alignment. For example, it could be protein structures or secondary structures. - pattern: "*" - ontologies: [] + ontologies: + - edam: http://edamontology.org/format_1476 # PDB - compress: type: boolean description: Flag representing whether the output MSA should be compressed. Set @@ -74,7 +77,10 @@ output: type: file description: Alignment file in FASTA format. May be gzipped. pattern: "*.aln{.gz,}" - ontologies: [] + ontologies: + - edam: http://edamontology.org/format_2554 # ALIGNMENT FORMAT TXT + - edam: http://edamontology.org/format_1921 # ALIGNMENT FORMAT + - edam: http://edamontology.org/format_1984 # FASTA-ALN versions: - versions.yml: type: file diff --git a/modules/nf-core/upp/align/meta.yml b/modules/nf-core/upp/align/meta.yml index fccbe366dec1..fa568f9acaaf 100644 --- a/modules/nf-core/upp/align/meta.yml +++ b/modules/nf-core/upp/align/meta.yml @@ -25,7 +25,9 @@ input: type: file description: Input sequences in FASTA format pattern: "*.{fa,fasta}" - ontologies: [] + ontologies: + - edam: http://edamontology.org/format_1919 # SEQUENCE-LIKE + - edam: http://edamontology.org/format_1929 # FASTA - - meta2: type: map description: | @@ -35,7 +37,8 @@ input: type: file description: Input guide tree in Newick format pattern: "*.{dnd}" - ontologies: [] + ontologies: + - edam: http://edamontology.org/format_2006 # PHYLOGENETIC TREE - compress: type: boolean description: Flag representing whether the output MSA should be compressed. Set @@ -52,7 +55,10 @@ output: description: Alignment file, in FASTA format. May be gzipped or uncompressed, depending on if compress is set to true or false pattern: "*.aln{.gz,}" - ontologies: [] + ontologies: + - edam: http://edamontology.org/format_2554 # ALIGNMENT FORMAT TXT + - edam: http://edamontology.org/format_1921 # ALIGNMENT FORMAT + - edam: http://edamontology.org/format_1984 # FASTA-ALN versions: - versions.yml: type: file From a03e263b425baece7b8e85a8542dce48a4c90595 Mon Sep 17 00:00:00 2001 From: Hanh Hoang <134130358+sainsachiko@users.noreply.github.com> Date: Mon, 1 Dec 2025 21:18:33 +0700 Subject: [PATCH 03/83] Add module PBMARKDUP (#9457) * Add module pbmarkdup * Fix linting * Update path to test data * Update with code review (--dup-file, log, check file name collisions) * Fix linting * Update path to test data * Update modules/nf-core/pbmarkdup/meta.yml * Fix linting --- modules/nf-core/pbmarkdup/environment.yml | 7 + modules/nf-core/pbmarkdup/main.nf | 73 +++++++ modules/nf-core/pbmarkdup/meta.yml | 90 ++++++++ modules/nf-core/pbmarkdup/tests/main.nf.test | 133 ++++++++++++ .../nf-core/pbmarkdup/tests/main.nf.test.snap | 202 ++++++++++++++++++ .../nf-core/pbmarkdup/tests/nextflow.config | 5 + 6 files changed, 510 insertions(+) create mode 100644 modules/nf-core/pbmarkdup/environment.yml create mode 100644 modules/nf-core/pbmarkdup/main.nf create mode 100644 modules/nf-core/pbmarkdup/meta.yml create mode 100644 modules/nf-core/pbmarkdup/tests/main.nf.test create mode 100644 modules/nf-core/pbmarkdup/tests/main.nf.test.snap create mode 100644 modules/nf-core/pbmarkdup/tests/nextflow.config diff --git a/modules/nf-core/pbmarkdup/environment.yml b/modules/nf-core/pbmarkdup/environment.yml new file mode 100644 index 000000000000..7e5a3099a716 --- /dev/null +++ b/modules/nf-core/pbmarkdup/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/sanger-tol/nf-core-modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::pbmarkdup=1.2.0 diff --git a/modules/nf-core/pbmarkdup/main.nf b/modules/nf-core/pbmarkdup/main.nf new file mode 100644 index 000000000000..20da004d21b5 --- /dev/null +++ b/modules/nf-core/pbmarkdup/main.nf @@ -0,0 +1,73 @@ +process PBMARKDUP { + tag "$meta.id" + label "process_high" + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/pbmarkdup:1.2.0--h9ee0642_0' : + 'biocontainers/pbmarkdup:1.2.0--h9ee0642_0' }" + + input: + tuple val(meta), path(input) + + output: + tuple val(meta), path("${prefix}.${suffix}"), emit: markduped + tuple val(meta), path("${dupfile_name}") , emit: dupfile , optional: true + tuple val(meta), path("*.pbmarkdup.log") , emit: log , optional: true + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + suffix = input[0].getExtension() // To allow multiple input types + dupfile_name = args.contains('--dup-file') ? (args =~ /--dup-file\s+(\S+)/)[0][1] : '' + def log_args = args.contains('--log-level') ? " > ${prefix}.pbmarkdup.log" : '' + def file_list = input.collect { it.getName() }.join(' ') + + // Check file name collisions between input, output, and duplicate file + if (file_list.contains("${prefix}.${suffix}")) + error """Output file `${prefix}.${suffix}` conflicts with an input file. + Please change the output `$prefix` or input file names.""" + if (dupfile_name) { + if (file_list.contains(dupfile_name)) + error """Duplicate file `$dupfile_name` conflicts with an input file. + Please change the duplicate file name `$dupfile_name` or input file names.""" + + if (dupfile_name == "${prefix}.${suffix}") + error """Duplicate file `$dupfile_name` cannot be the same as the output file name. + Please change the duplicate file name `$dupfile_name` or output prefix `$prefix`.""" + } + + """ + pbmarkdup \\ + -j ${task.cpus} \\ + ${file_list} \\ + ${prefix}.${suffix} \\ + $args \\ + ${log_args} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + pbmarkdup: \$(echo \$(pbmarkdup --version 2>&1) | awk 'BEFORE{FS=" "}{print \$2}') + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + suffix = input[0].getExtension() // To allow multiple input types + dupfile_name = args.contains('--dup-file') ? (args =~ /--dup-file\s+(\S+)/)[0][1] : '' + def log_args = args.contains('--log-level') ? " > ${prefix}.pbmarkdup.log" : '' + def file_list = input.collect { it.getName() }.join(' ') + """ + touch ${prefix}.${suffix} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + pbmarkdup: \$(echo \$(pbmarkdup --version 2>&1) | awk 'BEFORE{FS=" "}{print \$2}') + END_VERSIONS + """ +} diff --git a/modules/nf-core/pbmarkdup/meta.yml b/modules/nf-core/pbmarkdup/meta.yml new file mode 100644 index 000000000000..59a1de054258 --- /dev/null +++ b/modules/nf-core/pbmarkdup/meta.yml @@ -0,0 +1,90 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "pbmarkdup" +description: | + Takes one or multiple sequencing chips of an amplified library as HiFi reads and marks or removes + duplicates. +keywords: + - markdup + - bam + - fastq + - fasta +tools: + - pbmarkdup: + description: | + pbmarkdup identifies and marks duplicate reads in PacBio HiFi (CCS) data. It clusters + highly similar CCS reads to detect PCR duplicates and flags them in the output files + (BAM,FASTQ,FASTA) (duplicate bit 0x400), optionally removing duplicates. + (duplicate bit 0x400), optionally removing duplicates. + homepage: https://github.com/PacificBiosciences/pbmarkdup + documentation: https://github.com/PacificBiosciences/pbmarkdup + licence: ["BSD-3-Clause"] + identifier: biotools:pbmarkdup +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - input: + type: file + description: | + Sequencing reads in BAM, FASTQ, or FASTA format. + pattern: "*.{bam,f*a,/.*f.*\\.gz/}" + ontologies: + - edam: http://edamontology.org/format_2546 # FASTA-like + - edam: "http://edamontology.org/format_1930" # FASTQ + - edam: "http://edamontology.org/format_2572" # BAM +output: + markduped: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - ${prefix}.${suffix}: + type: file + description: | + Markduplicated sequencing reads in the same format as the input file. + pattern: "*.{bam,f*a,/.*f.*\\.gz/}" + ontologies: + - edam: http://edamontology.org/format_2546 # FASTA-like + - edam: "http://edamontology.org/format_1930" # FASTQ + - edam: "http://edamontology.org/format_2572" # BAM + dupfile: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - ${dupfile_name}: + type: file + description: | + (Optional) File listing duplicate reads (Specify by --dup-file). + pattern: "*.{bam,f*a,/.*f.*\\.gz/}" + ontologies: + - edam: http://edamontology.org/format_2546 # FASTA-like + - edam: "http://edamontology.org/format_1930" # FASTQ + - edam: "http://edamontology.org/format_2572" # BAM + log: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.pbmarkdup.log": + type: file + description: | + Log file generated by pbmarkdup (if --log-level is specified). + pattern: "*.pbmarkdup.log" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@sainsachiko" +maintainers: + - "@sainsachiko" diff --git a/modules/nf-core/pbmarkdup/tests/main.nf.test b/modules/nf-core/pbmarkdup/tests/main.nf.test new file mode 100644 index 000000000000..dbe78c3517cc --- /dev/null +++ b/modules/nf-core/pbmarkdup/tests/main.nf.test @@ -0,0 +1,133 @@ + +nextflow_process { + + name "Test Process PBMARKDUP" + script "../main.nf" + process "PBMARKDUP" + + tag "modules" + tag "modules_nfcore" + tag "pbmarkdup" + + config './nextflow.config' + + test("deilephila porcellus - fasta") { + + when { + + params { + pbmarkdup_args = "--clobber" + } + + process { + """ + input[0] = Channel.of( + [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/eukaryotes/deilephila_porcellus/mito/ilDeiPorc1.HiFi.reads.fa', checkIfExists: true) + ] + ) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("acropora cervicornis - bam - multiple tests with dupfile and log") { + when { + + params { + pbmarkdup_args = "--clobber --dup-file ${prefix}.dup.bam --log-level INFO" + } + + process { + """ + input[0] = Channel.of( + [ + [ id:'test' ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/eukaryotes/acropora_cervicornis/m84093_241116_151316_s2.hifi_reads.bc2028.subset.1.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/eukaryotes/acropora_cervicornis/m84093_241116_151316_s2.hifi_reads.bc2028.subset.2.bam', checkIfExists: true) + ] + ] + ) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("acropora cervicornis - bam - multiple tests remove duplicates") { + when { + + params { + pbmarkdup_args = "--clobber --rmdup" + } + + process { + """ + input[0] = Channel.of( + [ + [ id:'test' ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/eukaryotes/acropora_cervicornis/m84093_241116_151316_s2.hifi_reads.bc2028.subset.1.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/eukaryotes/acropora_cervicornis/m84093_241116_151316_s2.hifi_reads.bc2028.subset.2.bam', checkIfExists: true) + ] + ] + ) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("deilephila porcellus - stub") { + + options "-stub" + + when { + params { + pbmarkdup_args = "" + } + + process { + """ + input[0] = Channel.of( + [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/eukaryotes/deilephila_porcellus/mito/ilDeiPorc1.HiFi.reads.fa', checkIfExists: true) + ] + ) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/pbmarkdup/tests/main.nf.test.snap b/modules/nf-core/pbmarkdup/tests/main.nf.test.snap new file mode 100644 index 000000000000..705b7dd4f2ac --- /dev/null +++ b/modules/nf-core/pbmarkdup/tests/main.nf.test.snap @@ -0,0 +1,202 @@ +{ + "acropora cervicornis - bam - multiple tests remove duplicates": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bam:md5,86e22a794d904cc48cb3758a03883ba1" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,832e36b56615fb29a94b16e4db32b8db" + ], + "dupfile": [ + + ], + "log": [ + + ], + "markduped": [ + [ + { + "id": "test" + }, + "test.bam:md5,86e22a794d904cc48cb3758a03883ba1" + ] + ], + "versions": [ + "versions.yml:md5,832e36b56615fb29a94b16e4db32b8db" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.2" + }, + "timestamp": "2025-11-27T22:25:53.428359" + }, + "acropora cervicornis - bam - multiple tests with dupfile and log": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bam:md5,86e22a794d904cc48cb3758a03883ba1" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "null.dup.bam:md5,3b74225ad5f7e9e1cbafc45132ad82fb" + ] + ], + "2": [ + [ + { + "id": "test" + }, + "test.pbmarkdup.log:md5,99987a1331d01b59aa3b5ccd1c787906" + ] + ], + "3": [ + "versions.yml:md5,832e36b56615fb29a94b16e4db32b8db" + ], + "dupfile": [ + [ + { + "id": "test" + }, + "null.dup.bam:md5,3b74225ad5f7e9e1cbafc45132ad82fb" + ] + ], + "log": [ + [ + { + "id": "test" + }, + "test.pbmarkdup.log:md5,99987a1331d01b59aa3b5ccd1c787906" + ] + ], + "markduped": [ + [ + { + "id": "test" + }, + "test.bam:md5,86e22a794d904cc48cb3758a03883ba1" + ] + ], + "versions": [ + "versions.yml:md5,832e36b56615fb29a94b16e4db32b8db" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.2" + }, + "timestamp": "2025-11-27T22:25:23.374664" + }, + "deilephila porcellus - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.fa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,832e36b56615fb29a94b16e4db32b8db" + ], + "dupfile": [ + + ], + "log": [ + + ], + "markduped": [ + [ + { + "id": "test" + }, + "test.fa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,832e36b56615fb29a94b16e4db32b8db" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.2" + }, + "timestamp": "2025-11-27T22:26:16.491708" + }, + "deilephila porcellus - fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.fa:md5,087cee5291f8d728a62b91765b64af35" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,832e36b56615fb29a94b16e4db32b8db" + ], + "dupfile": [ + + ], + "log": [ + + ], + "markduped": [ + [ + { + "id": "test" + }, + "test.fa:md5,087cee5291f8d728a62b91765b64af35" + ] + ], + "versions": [ + "versions.yml:md5,832e36b56615fb29a94b16e4db32b8db" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.2" + }, + "timestamp": "2025-11-27T22:47:33.595865" + } +} \ No newline at end of file diff --git a/modules/nf-core/pbmarkdup/tests/nextflow.config b/modules/nf-core/pbmarkdup/tests/nextflow.config new file mode 100644 index 000000000000..dc9b092f0130 --- /dev/null +++ b/modules/nf-core/pbmarkdup/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: PBMARKDUP { + ext.args = { "${params.pbmarkdup_args}" } + } +} From e5052446d4e012b42507e8be3b6d1c7df461e62e Mon Sep 17 00:00:00 2001 From: Delfina Terradas <155591053+delfiterradas@users.noreply.github.com> Date: Mon, 1 Dec 2025 12:57:46 -0300 Subject: [PATCH 04/83] Enable complex contrast strings in DESeq2 (#9473) * Enable complex contrast strings * Update docker image * Add test case with limma contrast string * Format changes and add test with shrinkage --- .../deseq2/differential/environment.yml | 1 + modules/nf-core/deseq2/differential/main.nf | 4 +- .../templates/deseq2_differential.R | 31 +- .../tests/contrasts_shrink.config | 5 + .../deseq2/differential/tests/main.nf.test | 96 +++++ .../differential/tests/main.nf.test.snap | 332 ++++++++++++------ 6 files changed, 357 insertions(+), 112 deletions(-) create mode 100644 modules/nf-core/deseq2/differential/tests/contrasts_shrink.config diff --git a/modules/nf-core/deseq2/differential/environment.yml b/modules/nf-core/deseq2/differential/environment.yml index 4070836817b3..b069038c248d 100644 --- a/modules/nf-core/deseq2/differential/environment.yml +++ b/modules/nf-core/deseq2/differential/environment.yml @@ -5,3 +5,4 @@ channels: - bioconda dependencies: - bioconda::bioconductor-deseq2=1.34.0 + - bioconda::bioconductor-limma=3.50.0 diff --git a/modules/nf-core/deseq2/differential/main.nf b/modules/nf-core/deseq2/differential/main.nf index fccb86dbb810..e71d5a0685c8 100644 --- a/modules/nf-core/deseq2/differential/main.nf +++ b/modules/nf-core/deseq2/differential/main.nf @@ -4,8 +4,8 @@ process DESEQ2_DIFFERENTIAL { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bioconductor-deseq2:1.34.0--r41hc247a5b_3' : - 'biocontainers/bioconductor-deseq2:1.34.0--r41hc247a5b_3' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/a1/a15f5d61792b60b6179afd885db27d3fe60eb4c42e805c8887ed0416d88cb484/data' : + 'community.wave.seqera.io/library/bioconductor-deseq2_bioconductor-limma:b56a0c9ddc3e87e1' }" input: tuple val(meta), val(contrast_variable), val(reference), val(target), val(formula), val(comparison) diff --git a/modules/nf-core/deseq2/differential/templates/deseq2_differential.R b/modules/nf-core/deseq2/differential/templates/deseq2_differential.R index cded245c92b2..148e84139277 100755 --- a/modules/nf-core/deseq2/differential/templates/deseq2_differential.R +++ b/modules/nf-core/deseq2/differential/templates/deseq2_differential.R @@ -231,6 +231,7 @@ for (file_input in c('count_file', 'sample_file')){ library(DESeq2) library(BiocParallel) +library(limma) ################################################ ################################################ @@ -425,17 +426,25 @@ dds <- DESeq( if (!is.null(opt\$contrast_string)) { coef_names <- resultsNames(dds) - if (!(opt\$contrast_string %in% coef_names)) { - stop(sprintf( - "Contrast '%s' not in design. Available coefficients: %s", - opt\$contrast_string, - paste(coef_names, collapse = ", ") - )) - } + if (opt\$contrast_string %in% coef_names) { + # Direct coefficient name + comp.results <- run_results(name = opt\$contrast_string) + if (opt\$shrink_lfc) { + comp.results <- run_shrink(coef = opt\$contrast_string) + } + } else { + # Parse as limma-style contrast expression + design_mat <- model.matrix(as.formula(model), data = as.data.frame(colData(dds))) + colnames(design_mat) <- make.names(colnames(design_mat)) + numeric_contrast <- as.numeric( + limma::makeContrasts(contrasts = opt\$contrast_string, levels = colnames(design_mat)) + ) - comp.results <- run_results(name = opt\$contrast_string) - if (opt\$shrink_lfc) { - comp.results <- run_shrink(coef = opt\$contrast_string) + # Run DESeq2 results with numeric contrast + comp.results <- run_results(contrast = numeric_contrast) + if (opt\$shrink_lfc) { + comp.results <- run_shrink(contrast = numeric_contrast) + } } } else { contrast_var_tg_ref <- c(contrast_variable, @@ -452,7 +461,7 @@ if (!is.null(opt\$contrast_string)) { if (!is.null(opt\$transcript_lengths_file)){ size_factors = estimateSizeFactorsForMatrix(counts(dds) / assays(dds)[["avgTxLength"]]) -}else { +} else { size_factors = sizeFactors(dds) } diff --git a/modules/nf-core/deseq2/differential/tests/contrasts_shrink.config b/modules/nf-core/deseq2/differential/tests/contrasts_shrink.config new file mode 100644 index 000000000000..36f567c77113 --- /dev/null +++ b/modules/nf-core/deseq2/differential/tests/contrasts_shrink.config @@ -0,0 +1,5 @@ +process { + withName: 'DESEQ2_DIFFERENTIAL' { + ext.args = { "--round_digits 2 --sample_id_col sample --vs_method rlog --shrink_lfc TRUE --seed 1" } + } +} diff --git a/modules/nf-core/deseq2/differential/tests/main.nf.test b/modules/nf-core/deseq2/differential/tests/main.nf.test index c3d7a144be1b..3f3b1defc6c7 100644 --- a/modules/nf-core/deseq2/differential/tests/main.nf.test +++ b/modules/nf-core/deseq2/differential/tests/main.nf.test @@ -57,6 +57,102 @@ nextflow_process { } } + test("RNAseq - Feature Counts - formula + limma contrast string - interaction") { + config './contrasts_interaction.config' + + when { + process { + """ + input[0] = Channel.of([ + 'id': 'genotype_WT_KO', + 'formula': '~ 0 + genotype', + 'comparison': 'genotypeWT - genotypeKO' + ]) + .map { + tuple(it, it.variable, it.reference, it.target, it.formula, it.comparison) + } + + input[1] = Channel.of([ + [ id: 'test' ], + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/variancepartition_dream/metadata.tsv", checkIfExists: true), + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/variancepartition_dream/counts.tsv", checkIfExists: true) + ]) + + ch_spikes = [[],[]] + ch_lengths = [[],[]] + input[2] = ch_spikes + input[3] = ch_lengths + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.results, + process.out.size_factors, + process.out.normalised_counts, + process.out.rlog_counts, + process.out.vst_counts, + process.out.model, + process.out.versions, + file(process.out.dispersion_plot[0][1]).name, + file(process.out.rdata[0][1]).name + ).match() }, + { assert path(process.out.session_info[0][1]).text.contains("DESeq2_1.34.0") } + ) + } + } + + test("RNAseq - Feature Counts - formula + limma contrast string - shrunken") { + config './contrasts_shrink.config' + + when { + process { + """ + input[0] = Channel.of([ + 'id': 'genotype_WT_KO', + 'formula': '~ 0 + genotype', + 'comparison': 'genotypeWT - genotypeKO' + ]) + .map { + tuple(it, it.variable, it.reference, it.target, it.formula, it.comparison) + } + + input[1] = Channel.of([ + [ id: 'test' ], + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/variancepartition_dream/metadata.tsv", checkIfExists: true), + file("https://github.com/nf-core/test-datasets/raw/differentialabundance/modules_testdata/variancepartition_dream/counts.tsv", checkIfExists: true) + ]) + + ch_spikes = [[],[]] + ch_lengths = [[],[]] + input[2] = ch_spikes + input[3] = ch_lengths + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.results, + process.out.size_factors, + process.out.normalised_counts, + process.out.rlog_counts, + process.out.vst_counts, + process.out.model, + process.out.versions, + file(process.out.dispersion_plot[0][1]).name, + file(process.out.rdata[0][1]).name + ).match() }, + { assert path(process.out.session_info[0][1]).text.contains("DESeq2_1.34.0") } + ) + } + } + test("mouse - contrasts - matrix") { config './contrasts_matrix.config' diff --git a/modules/nf-core/deseq2/differential/tests/main.nf.test.snap b/modules/nf-core/deseq2/differential/tests/main.nf.test.snap index 527207a53d38..5758806568f6 100644 --- a/modules/nf-core/deseq2/differential/tests/main.nf.test.snap +++ b/modules/nf-core/deseq2/differential/tests/main.nf.test.snap @@ -66,7 +66,7 @@ }, "timestamp": "2025-07-20T23:45:08.311820361" }, - "mouse - contrasts - matrix - no blocking": { + "mouse - contrasts - matrix": { "content": [ [ [ @@ -192,9 +192,9 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-20T23:46:48.686505916" + "timestamp": "2025-07-20T23:45:40.047043298" }, - "mouse - contrasts - matrix": { + "mouse - contrasts - matrix - exclude samples": { "content": [ [ [ @@ -205,7 +205,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.deseq2.results.tsv:md5,791cdba2615a445cded13cae95df73ef" + "treatment_mCherry_hND6_.deseq2.results.tsv:md5,7d28d65b7ab94306c1328027a6531405" ], [ { @@ -215,7 +215,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.deseq2.results.tsv:md5,2438053a4bdc869f467a12d3c22c7ba7" + "treatment_mCherry_hND6_sample_number.deseq2.results.tsv:md5,f509c2de7d6935942eff594a0aca662e" ] ], [ @@ -227,7 +227,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.deseq2.sizefactors.tsv:md5,6332f21889ecac387bb12eeb04f23849" + "treatment_mCherry_hND6_.deseq2.sizefactors.tsv:md5,87d6d634ffea2d7a9df9f9bae91b4d90" ], [ { @@ -237,7 +237,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.deseq2.sizefactors.tsv:md5,6332f21889ecac387bb12eeb04f23849" + "treatment_mCherry_hND6_sample_number.deseq2.sizefactors.tsv:md5,87d6d634ffea2d7a9df9f9bae91b4d90" ] ], [ @@ -249,7 +249,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.normalised_counts.tsv:md5,46ab7200c626649ab6256ed797ef5071" + "treatment_mCherry_hND6_.normalised_counts.tsv:md5,90327e9bfc3bbafb96e11b13b3cd5e19" ], [ { @@ -259,7 +259,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.normalised_counts.tsv:md5,46ab7200c626649ab6256ed797ef5071" + "treatment_mCherry_hND6_sample_number.normalised_counts.tsv:md5,90327e9bfc3bbafb96e11b13b3cd5e19" ] ], [ @@ -271,7 +271,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.rlog.tsv:md5,b1adc1fba6bd0c8b55973608f4b97030" + "treatment_mCherry_hND6_.rlog.tsv:md5,c500bcad14f845113f85610d1ebf643c" ], [ { @@ -281,7 +281,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.rlog.tsv:md5,b1adc1fba6bd0c8b55973608f4b97030" + "treatment_mCherry_hND6_sample_number.rlog.tsv:md5,c500bcad14f845113f85610d1ebf643c" ] ], [ @@ -320,9 +320,9 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-20T23:45:40.047043298" + "timestamp": "2025-07-20T23:49:51.329803172" }, - "mouse - contrasts - matrix - exclude samples": { + "mouse - contrasts - matrix - lengths": { "content": [ [ [ @@ -333,7 +333,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.deseq2.results.tsv:md5,7d28d65b7ab94306c1328027a6531405" + "treatment_mCherry_hND6_.deseq2.results.tsv:md5,944176b73455aa7c8de3ec32c03edef6" ], [ { @@ -343,7 +343,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.deseq2.results.tsv:md5,f509c2de7d6935942eff594a0aca662e" + "treatment_mCherry_hND6_sample_number.deseq2.results.tsv:md5,6a9bc76c9d54034c90fa159372f97516" ] ], [ @@ -355,7 +355,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.deseq2.sizefactors.tsv:md5,87d6d634ffea2d7a9df9f9bae91b4d90" + "treatment_mCherry_hND6_.deseq2.sizefactors.tsv:md5,69183b94202a806067962d0df0b9875b" ], [ { @@ -365,7 +365,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.deseq2.sizefactors.tsv:md5,87d6d634ffea2d7a9df9f9bae91b4d90" + "treatment_mCherry_hND6_sample_number.deseq2.sizefactors.tsv:md5,69183b94202a806067962d0df0b9875b" ] ], [ @@ -377,7 +377,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.normalised_counts.tsv:md5,90327e9bfc3bbafb96e11b13b3cd5e19" + "treatment_mCherry_hND6_.normalised_counts.tsv:md5,7050f44c460cc13e3f101d048d503527" ], [ { @@ -387,7 +387,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.normalised_counts.tsv:md5,90327e9bfc3bbafb96e11b13b3cd5e19" + "treatment_mCherry_hND6_sample_number.normalised_counts.tsv:md5,7050f44c460cc13e3f101d048d503527" ] ], [ @@ -399,7 +399,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.rlog.tsv:md5,c500bcad14f845113f85610d1ebf643c" + "treatment_mCherry_hND6_.rlog.tsv:md5,22a4b117246b2317e0f4daf7919703f2" ], [ { @@ -409,7 +409,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.rlog.tsv:md5,c500bcad14f845113f85610d1ebf643c" + "treatment_mCherry_hND6_sample_number.rlog.tsv:md5,22a4b117246b2317e0f4daf7919703f2" ] ], [ @@ -448,9 +448,9 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-20T23:49:51.329803172" + "timestamp": "2025-07-20T23:46:16.333966759" }, - "mouse - contrasts - matrix - lengths": { + "mouse - contrasts - matrix - strip spikes": { "content": [ [ [ @@ -461,7 +461,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.deseq2.results.tsv:md5,944176b73455aa7c8de3ec32c03edef6" + "treatment_mCherry_hND6_.deseq2.results.tsv:md5,c4d269cace6dfe42e81e39d13b4b0354" ], [ { @@ -471,7 +471,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.deseq2.results.tsv:md5,6a9bc76c9d54034c90fa159372f97516" + "treatment_mCherry_hND6_sample_number.deseq2.results.tsv:md5,e1820951d5d5c40fa7fd6368e8f62e8c" ] ], [ @@ -483,7 +483,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.deseq2.sizefactors.tsv:md5,69183b94202a806067962d0df0b9875b" + "treatment_mCherry_hND6_.deseq2.sizefactors.tsv:md5,a526a1bb5cb270f5a4a1641fefd289b3" ], [ { @@ -493,7 +493,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.deseq2.sizefactors.tsv:md5,69183b94202a806067962d0df0b9875b" + "treatment_mCherry_hND6_sample_number.deseq2.sizefactors.tsv:md5,a526a1bb5cb270f5a4a1641fefd289b3" ] ], [ @@ -505,7 +505,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.normalised_counts.tsv:md5,7050f44c460cc13e3f101d048d503527" + "treatment_mCherry_hND6_.normalised_counts.tsv:md5,89c5922a30218a17ab6ee84e031f6a9b" ], [ { @@ -515,7 +515,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.normalised_counts.tsv:md5,7050f44c460cc13e3f101d048d503527" + "treatment_mCherry_hND6_sample_number.normalised_counts.tsv:md5,89c5922a30218a17ab6ee84e031f6a9b" ] ], [ @@ -527,7 +527,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.rlog.tsv:md5,22a4b117246b2317e0f4daf7919703f2" + "treatment_mCherry_hND6_.rlog.tsv:md5,4b4526ddcca010f5c75f841b2cef269f" ], [ { @@ -537,7 +537,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.rlog.tsv:md5,22a4b117246b2317e0f4daf7919703f2" + "treatment_mCherry_hND6_sample_number.rlog.tsv:md5,4b4526ddcca010f5c75f841b2cef269f" ] ], [ @@ -576,54 +576,77 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-20T23:46:16.333966759" + "timestamp": "2025-07-20T23:47:46.184431379" }, - "mouse - contrasts - matrix - strip spikes": { + "RNAseq - Feature Counts - formula + limma contrast string - interaction": { "content": [ [ [ { - "id": "treatment_mCherry_hND6_", - "variable": "treatment", - "reference": "mCherry", - "target": "hND6", - "blocking": "" + "id": "genotype_WT_KO", + "formula": "~ 0 + genotype", + "comparison": "genotypeWT - genotypeKO" }, - "treatment_mCherry_hND6_.deseq2.results.tsv:md5,c4d269cace6dfe42e81e39d13b4b0354" - ], + "genotype_WT_KO.deseq2.results.tsv:md5,59256d9c5b4f12e4422dcf80776da841" + ] + ], + [ [ { - "id": "treatment_mCherry_hND6_sample_number", - "variable": "treatment", - "reference": "mCherry", - "target": "hND6", - "blocking": "sample_number" + "id": "genotype_WT_KO", + "formula": "~ 0 + genotype", + "comparison": "genotypeWT - genotypeKO" }, - "treatment_mCherry_hND6_sample_number.deseq2.results.tsv:md5,e1820951d5d5c40fa7fd6368e8f62e8c" + "genotype_WT_KO.deseq2.sizefactors.tsv:md5,0367d1ef76c5b9f01fc1f89647809b5d" ] ], [ [ { - "id": "treatment_mCherry_hND6_", - "variable": "treatment", - "reference": "mCherry", - "target": "hND6", - "blocking": "" + "id": "genotype_WT_KO", + "formula": "~ 0 + genotype", + "comparison": "genotypeWT - genotypeKO" }, - "treatment_mCherry_hND6_.deseq2.sizefactors.tsv:md5,a526a1bb5cb270f5a4a1641fefd289b3" - ], + "genotype_WT_KO.normalised_counts.tsv:md5,6d9d7c02be9169ba4a649f8fb0f0b7ea" + ] + ], + [ [ { - "id": "treatment_mCherry_hND6_sample_number", - "variable": "treatment", - "reference": "mCherry", - "target": "hND6", - "blocking": "sample_number" + "id": "genotype_WT_KO", + "formula": "~ 0 + genotype", + "comparison": "genotypeWT - genotypeKO" }, - "treatment_mCherry_hND6_sample_number.deseq2.sizefactors.tsv:md5,a526a1bb5cb270f5a4a1641fefd289b3" + "genotype_WT_KO.rlog.tsv:md5,0e9d0074e4acc651f50234fcce55a1cf" + ] + ], + [ + + ], + [ + [ + { + "id": "genotype_WT_KO", + "formula": "~ 0 + genotype", + "comparison": "genotypeWT - genotypeKO" + }, + "genotype_WT_KO.deseq2.model.txt:md5,ac7205ad2d20dc34aedba90032d06629" ] ], + [ + "versions.yml:md5,62c34d4f3d11c2bdbe2e4f7e6086b35e" + ], + "genotype_WT_KO.deseq2.dispersion.png", + "genotype_WT_KO.dds.rld.rds" + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-27T19:01:59.05302518" + }, + "mouse - contrasts - matrix - csv": { + "content": [ [ [ { @@ -633,17 +656,19 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.normalised_counts.tsv:md5,89c5922a30218a17ab6ee84e031f6a9b" - ], + "treatment_mCherry_hND6_.deseq2.results.tsv:md5,791cdba2615a445cded13cae95df73ef" + ] + ], + [ [ { - "id": "treatment_mCherry_hND6_sample_number", + "id": "treatment_mCherry_hND6_", "variable": "treatment", "reference": "mCherry", "target": "hND6", - "blocking": "sample_number" + "blocking": "" }, - "treatment_mCherry_hND6_sample_number.normalised_counts.tsv:md5,89c5922a30218a17ab6ee84e031f6a9b" + "treatment_mCherry_hND6_.deseq2.sizefactors.tsv:md5,6332f21889ecac387bb12eeb04f23849" ] ], [ @@ -655,17 +680,19 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.rlog.tsv:md5,4b4526ddcca010f5c75f841b2cef269f" - ], + "treatment_mCherry_hND6_.normalised_counts.tsv:md5,46ab7200c626649ab6256ed797ef5071" + ] + ], + [ [ { - "id": "treatment_mCherry_hND6_sample_number", + "id": "treatment_mCherry_hND6_", "variable": "treatment", "reference": "mCherry", "target": "hND6", - "blocking": "sample_number" + "blocking": "" }, - "treatment_mCherry_hND6_sample_number.rlog.tsv:md5,4b4526ddcca010f5c75f841b2cef269f" + "treatment_mCherry_hND6_.rlog.tsv:md5,b1adc1fba6bd0c8b55973608f4b97030" ] ], [ @@ -681,20 +708,9 @@ "blocking": "" }, "treatment_mCherry_hND6_.deseq2.model.txt:md5,d2113d82b76046c319e6602da2ad74d6" - ], - [ - { - "id": "treatment_mCherry_hND6_sample_number", - "variable": "treatment", - "reference": "mCherry", - "target": "hND6", - "blocking": "sample_number" - }, - "treatment_mCherry_hND6_sample_number.deseq2.model.txt:md5,fa05126a58cb67c107d45426b0bdea83" ] ], [ - "versions.yml:md5,62c34d4f3d11c2bdbe2e4f7e6086b35e", "versions.yml:md5,62c34d4f3d11c2bdbe2e4f7e6086b35e" ], "treatment_mCherry_hND6_.deseq2.dispersion.png", @@ -704,9 +720,9 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-20T23:47:46.184431379" + "timestamp": "2025-07-20T23:48:13.859007527" }, - "mouse - contrasts - matrix - subset to contrast": { + "mouse - contrasts - matrix - no blocking": { "content": [ [ [ @@ -832,9 +848,76 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-20T23:49:13.891655952" + "timestamp": "2025-07-20T23:46:48.686505916" }, - "mouse - contrasts - matrix - spikes": { + "RNAseq - Feature Counts - formula + limma contrast string - shrunken": { + "content": [ + [ + [ + { + "id": "genotype_WT_KO", + "formula": "~ 0 + genotype", + "comparison": "genotypeWT - genotypeKO" + }, + "genotype_WT_KO.deseq2.results.tsv:md5,23511305c222de275f888fee844f055c" + ] + ], + [ + [ + { + "id": "genotype_WT_KO", + "formula": "~ 0 + genotype", + "comparison": "genotypeWT - genotypeKO" + }, + "genotype_WT_KO.deseq2.sizefactors.tsv:md5,0367d1ef76c5b9f01fc1f89647809b5d" + ] + ], + [ + [ + { + "id": "genotype_WT_KO", + "formula": "~ 0 + genotype", + "comparison": "genotypeWT - genotypeKO" + }, + "genotype_WT_KO.normalised_counts.tsv:md5,6d9d7c02be9169ba4a649f8fb0f0b7ea" + ] + ], + [ + [ + { + "id": "genotype_WT_KO", + "formula": "~ 0 + genotype", + "comparison": "genotypeWT - genotypeKO" + }, + "genotype_WT_KO.rlog.tsv:md5,0e9d0074e4acc651f50234fcce55a1cf" + ] + ], + [ + + ], + [ + [ + { + "id": "genotype_WT_KO", + "formula": "~ 0 + genotype", + "comparison": "genotypeWT - genotypeKO" + }, + "genotype_WT_KO.deseq2.model.txt:md5,ac7205ad2d20dc34aedba90032d06629" + ] + ], + [ + "versions.yml:md5,62c34d4f3d11c2bdbe2e4f7e6086b35e" + ], + "genotype_WT_KO.deseq2.dispersion.png", + "genotype_WT_KO.dds.rld.rds" + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-28T15:42:51.742301418" + }, + "mouse - contrasts - matrix - subset to contrast": { "content": [ [ [ @@ -845,7 +928,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.deseq2.results.tsv:md5,51ba90cf073d9d5f38ebb043d7e5b220" + "treatment_mCherry_hND6_.deseq2.results.tsv:md5,791cdba2615a445cded13cae95df73ef" ], [ { @@ -855,7 +938,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.deseq2.results.tsv:md5,a04e2df3712d5be27e39c50f83319ec4" + "treatment_mCherry_hND6_sample_number.deseq2.results.tsv:md5,2438053a4bdc869f467a12d3c22c7ba7" ] ], [ @@ -867,7 +950,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.deseq2.sizefactors.tsv:md5,1708374146b4e8c28fbc78fa292102cd" + "treatment_mCherry_hND6_.deseq2.sizefactors.tsv:md5,6332f21889ecac387bb12eeb04f23849" ], [ { @@ -877,7 +960,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.deseq2.sizefactors.tsv:md5,1708374146b4e8c28fbc78fa292102cd" + "treatment_mCherry_hND6_sample_number.deseq2.sizefactors.tsv:md5,6332f21889ecac387bb12eeb04f23849" ] ], [ @@ -889,7 +972,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.normalised_counts.tsv:md5,6f3af146a6f8fbb8f565dd66e79d2cb1" + "treatment_mCherry_hND6_.normalised_counts.tsv:md5,46ab7200c626649ab6256ed797ef5071" ], [ { @@ -899,7 +982,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.normalised_counts.tsv:md5,6f3af146a6f8fbb8f565dd66e79d2cb1" + "treatment_mCherry_hND6_sample_number.normalised_counts.tsv:md5,46ab7200c626649ab6256ed797ef5071" ] ], [ @@ -911,7 +994,7 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.rlog.tsv:md5,39df6fb2969afc009a602261e864238f" + "treatment_mCherry_hND6_.rlog.tsv:md5,b1adc1fba6bd0c8b55973608f4b97030" ], [ { @@ -921,7 +1004,7 @@ "target": "hND6", "blocking": "sample_number" }, - "treatment_mCherry_hND6_sample_number.rlog.tsv:md5,39df6fb2969afc009a602261e864238f" + "treatment_mCherry_hND6_sample_number.rlog.tsv:md5,b1adc1fba6bd0c8b55973608f4b97030" ] ], [ @@ -960,9 +1043,9 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-20T23:47:18.3338485" + "timestamp": "2025-07-20T23:49:13.891655952" }, - "mouse - contrasts - matrix - csv": { + "mouse - contrasts - matrix - spikes": { "content": [ [ [ @@ -973,7 +1056,17 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.deseq2.results.tsv:md5,791cdba2615a445cded13cae95df73ef" + "treatment_mCherry_hND6_.deseq2.results.tsv:md5,51ba90cf073d9d5f38ebb043d7e5b220" + ], + [ + { + "id": "treatment_mCherry_hND6_sample_number", + "variable": "treatment", + "reference": "mCherry", + "target": "hND6", + "blocking": "sample_number" + }, + "treatment_mCherry_hND6_sample_number.deseq2.results.tsv:md5,a04e2df3712d5be27e39c50f83319ec4" ] ], [ @@ -985,7 +1078,17 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.deseq2.sizefactors.tsv:md5,6332f21889ecac387bb12eeb04f23849" + "treatment_mCherry_hND6_.deseq2.sizefactors.tsv:md5,1708374146b4e8c28fbc78fa292102cd" + ], + [ + { + "id": "treatment_mCherry_hND6_sample_number", + "variable": "treatment", + "reference": "mCherry", + "target": "hND6", + "blocking": "sample_number" + }, + "treatment_mCherry_hND6_sample_number.deseq2.sizefactors.tsv:md5,1708374146b4e8c28fbc78fa292102cd" ] ], [ @@ -997,7 +1100,17 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.normalised_counts.tsv:md5,46ab7200c626649ab6256ed797ef5071" + "treatment_mCherry_hND6_.normalised_counts.tsv:md5,6f3af146a6f8fbb8f565dd66e79d2cb1" + ], + [ + { + "id": "treatment_mCherry_hND6_sample_number", + "variable": "treatment", + "reference": "mCherry", + "target": "hND6", + "blocking": "sample_number" + }, + "treatment_mCherry_hND6_sample_number.normalised_counts.tsv:md5,6f3af146a6f8fbb8f565dd66e79d2cb1" ] ], [ @@ -1009,7 +1122,17 @@ "target": "hND6", "blocking": "" }, - "treatment_mCherry_hND6_.rlog.tsv:md5,b1adc1fba6bd0c8b55973608f4b97030" + "treatment_mCherry_hND6_.rlog.tsv:md5,39df6fb2969afc009a602261e864238f" + ], + [ + { + "id": "treatment_mCherry_hND6_sample_number", + "variable": "treatment", + "reference": "mCherry", + "target": "hND6", + "blocking": "sample_number" + }, + "treatment_mCherry_hND6_sample_number.rlog.tsv:md5,39df6fb2969afc009a602261e864238f" ] ], [ @@ -1025,9 +1148,20 @@ "blocking": "" }, "treatment_mCherry_hND6_.deseq2.model.txt:md5,d2113d82b76046c319e6602da2ad74d6" + ], + [ + { + "id": "treatment_mCherry_hND6_sample_number", + "variable": "treatment", + "reference": "mCherry", + "target": "hND6", + "blocking": "sample_number" + }, + "treatment_mCherry_hND6_sample_number.deseq2.model.txt:md5,fa05126a58cb67c107d45426b0bdea83" ] ], [ + "versions.yml:md5,62c34d4f3d11c2bdbe2e4f7e6086b35e", "versions.yml:md5,62c34d4f3d11c2bdbe2e4f7e6086b35e" ], "treatment_mCherry_hND6_.deseq2.dispersion.png", @@ -1037,7 +1171,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-07-20T23:48:13.859007527" + "timestamp": "2025-07-20T23:47:18.3338485" }, "mouse - contrasts - matrix - vst nsub": { "content": [ From 26d580327e4d78bcdb440e80df2378ff0fc1a712 Mon Sep 17 00:00:00 2001 From: Peter Pruisscher <57712924+peterpru@users.noreply.github.com> Date: Tue, 2 Dec 2025 09:02:39 +0100 Subject: [PATCH 05/83] Declare deepvariant optional html output (#9469) * Add deepvariant optional html * update snapshot * Update modules/nf-core/deepvariant/rundeepvariant/main.nf Co-authored-by: Ramprasad Neethiraj <20065894+ramprasadn@users.noreply.github.com> * trigger html generation * revert config change --------- Co-authored-by: Ramprasad Neethiraj <20065894+ramprasadn@users.noreply.github.com> --- .../deepvariant/rundeepvariant/main.nf | 1 + .../deepvariant/rundeepvariant/meta.yml | 12 +++ .../rundeepvariant/tests/main.nf.test.snap | 74 ++++++++++++++----- .../rundeepvariant/tests/nextflow.config | 2 - 4 files changed, 68 insertions(+), 21 deletions(-) diff --git a/modules/nf-core/deepvariant/rundeepvariant/main.nf b/modules/nf-core/deepvariant/rundeepvariant/main.nf index 33da4675ed1c..d7f2a1d41b97 100644 --- a/modules/nf-core/deepvariant/rundeepvariant/main.nf +++ b/modules/nf-core/deepvariant/rundeepvariant/main.nf @@ -20,6 +20,7 @@ process DEEPVARIANT_RUNDEEPVARIANT { tuple val(meta), path("${prefix}.vcf.gz.{tbi,csi}") , emit: vcf_index tuple val(meta), path("${prefix}.g.vcf.gz") , emit: gvcf tuple val(meta), path("${prefix}.g.vcf.gz.{tbi,csi}") , emit: gvcf_index + tuple val(meta), path("${prefix}.visual_report.html") , emit: report, optional: true path "versions.yml" , emit: versions when: diff --git a/modules/nf-core/deepvariant/rundeepvariant/meta.yml b/modules/nf-core/deepvariant/rundeepvariant/meta.yml index 2c3ba0ad4142..6adc22b7c7e9 100644 --- a/modules/nf-core/deepvariant/rundeepvariant/meta.yml +++ b/modules/nf-core/deepvariant/rundeepvariant/meta.yml @@ -122,6 +122,18 @@ output: description: Tabix index file of compressed GVCF pattern: "*.g.vcf.gz.{tbi,csi}" ontologies: [] + report: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}.visual_report.html: + type: file + description: Visual report in HTML format + pattern: "*.html" + optional: true + ontologies: [] versions: - versions.yml: type: file diff --git a/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap b/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap index 25300a06934a..673c7013c23e 100644 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap +++ b/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap @@ -39,6 +39,9 @@ ] ], "4": [ + + ], + "5": [ "versions.yml:md5,3609b8b1430f8fa9038d70e359be0056" ], "gvcf": [ @@ -58,6 +61,9 @@ }, "test_out.g.vcf.gz.tbi:md5,1680c67fe988bc1d8220fbb4127c2c18" ] + ], + "report": [ + ], "vcf": [ [ @@ -83,10 +89,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-03-12T15:16:11.704882305" + "timestamp": "2025-11-28T13:05:09.499778645" }, "homo_sapiens - [bam, bai] - fasta - fai": { "content": [ @@ -128,6 +134,9 @@ ] ], "4": [ + + ], + "5": [ "versions.yml:md5,3609b8b1430f8fa9038d70e359be0056" ], "gvcf": [ @@ -147,6 +156,9 @@ }, "test_out.g.vcf.gz.tbi:md5,1680c67fe988bc1d8220fbb4127c2c18" ] + ], + "report": [ + ], "vcf": [ [ @@ -172,10 +184,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-03-12T15:14:44.890205274" + "timestamp": "2025-11-28T13:03:26.419020939" }, "homo_sapiens - [cram, crai, genome_bed] - fasta - fai": { "content": [ @@ -217,6 +229,9 @@ ] ], "4": [ + + ], + "5": [ "versions.yml:md5,3609b8b1430f8fa9038d70e359be0056" ], "gvcf": [ @@ -236,6 +251,9 @@ }, "test_out.g.vcf.gz.tbi:md5,1680c67fe988bc1d8220fbb4127c2c18" ] + ], + "report": [ + ], "vcf": [ [ @@ -261,10 +279,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-03-12T15:15:21.933753648" + "timestamp": "2025-11-28T13:04:01.115384036" }, "homo_sapiens - [cram, crai, genome_bed] - fasta - fai - par_bed": { "content": [ @@ -306,6 +324,9 @@ ] ], "4": [ + + ], + "5": [ "versions.yml:md5,3609b8b1430f8fa9038d70e359be0056" ], "gvcf": [ @@ -325,6 +346,9 @@ }, "test_out.g.vcf.gz.tbi:md5,673ce95e6701a5e7d58ea2ab93440b27" ] + ], + "report": [ + ], "vcf": [ [ @@ -350,10 +374,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-08-16T11:50:27.672287" + "timestamp": "2025-11-28T13:04:35.257314075" }, "homo_sapiens - [bam, bai] - fasta - fai - stub": { "content": [ @@ -395,6 +419,9 @@ ] ], "4": [ + + ], + "5": [ "versions.yml:md5,3609b8b1430f8fa9038d70e359be0056" ], "gvcf": [ @@ -414,6 +441,9 @@ }, "test_out.g.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" ] + ], + "report": [ + ], "vcf": [ [ @@ -439,10 +469,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-08-16T11:50:55.188159" + "timestamp": "2025-11-28T13:05:19.534057506" }, "homo_sapiens - [bam, bai] - fasta_gz - fasta_gz_fai - stub": { "content": [ @@ -484,6 +514,9 @@ ] ], "4": [ + + ], + "5": [ "versions.yml:md5,3609b8b1430f8fa9038d70e359be0056" ], "gvcf": [ @@ -503,6 +536,9 @@ }, "test_out.g.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" ] + ], + "report": [ + ], "vcf": [ [ @@ -528,9 +564,9 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-03-12T15:16:35.978912843" + "timestamp": "2025-11-28T13:05:29.423589845" } -} +} \ No newline at end of file diff --git a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config index 161183de4a4d..9693059b83d5 100644 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config +++ b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config @@ -1,8 +1,6 @@ process { - withName: DEEPVARIANT_RUNDEEPVARIANT { ext.args = params.module_args ext.prefix = { "${meta.id}_out" } } - } From dbadf9ceacfb9bd672bf9cbc1c1307f1dbd758b2 Mon Sep 17 00:00:00 2001 From: Matthias De Smet <11850640+matthdsm@users.noreply.github.com> Date: Tue, 2 Dec 2025 12:50:02 +0100 Subject: [PATCH 06/83] utils_nfcore_pipeline: fix small lang server error (#9492) fix small lang server error --- subworkflows/nf-core/utils_nfcore_pipeline/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf index 2f30e9a4632a..bfd258760d2b 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf @@ -98,7 +98,7 @@ def workflowVersionToYAML() { // Get channel of software versions used in pipeline in YAML format // def softwareVersionsToYAML(ch_versions) { - return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(channel.of(workflowVersionToYAML())) + return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(Channel.of(workflowVersionToYAML())) } // From e97aaf480275126b9ed2ec3d03ecbfed6081fd8e Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Tue, 2 Dec 2025 12:17:04 +0000 Subject: [PATCH 07/83] Fix hisat2/align to support large genome indices (.ht2l) (#9493) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HISAT2 uses .ht2l extension instead of .ht2 for large genomes. Updated index detection to match both extensions. Related to nf-core/rnaseq#1643 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude --- modules/nf-core/hisat2/align/main.nf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/nf-core/hisat2/align/main.nf b/modules/nf-core/hisat2/align/main.nf index 221f5ed976d6..898b09d21c05 100644 --- a/modules/nf-core/hisat2/align/main.nf +++ b/modules/nf-core/hisat2/align/main.nf @@ -36,7 +36,7 @@ process HISAT2_ALIGN { if (meta.single_end) { def unaligned = params.save_unaligned ? "--un-gz ${prefix}.unmapped.fastq.gz" : '' """ - INDEX=`find -L ./ -name "*.1.ht2" | sed 's/\\.1.ht2\$//'` + INDEX=`find -L ./ -name "*.1.ht2*" | sed 's/\\.1.ht2.*\$//'` hisat2 \\ -x \$INDEX \\ -U $reads \\ @@ -58,7 +58,7 @@ process HISAT2_ALIGN { } else { def unaligned = params.save_unaligned ? "--un-conc-gz ${prefix}.unmapped.fastq.gz" : '' """ - INDEX=`find -L ./ -name "*.1.ht2" | sed 's/\\.1.ht2\$//'` + INDEX=`find -L ./ -name "*.1.ht2*" | sed 's/\\.1.ht2.*\$//'` hisat2 \\ -x \$INDEX \\ -1 ${reads[0]} \\ From 51369d057e7ae6dfe6b4108a9bbacdf4bc35c8d1 Mon Sep 17 00:00:00 2001 From: Delfina Terradas <155591053+delfiterradas@users.noreply.github.com> Date: Tue, 2 Dec 2025 10:57:28 -0300 Subject: [PATCH 08/83] Update shinyngs modules to latest release (#9488) --- modules/nf-core/shinyngs/app/environment.yml | 2 +- modules/nf-core/shinyngs/app/main.nf | 4 +-- .../shinyngs/app/tests/main.nf.test.snap | 24 +++++++------- .../staticdifferential/environment.yml | 2 +- .../shinyngs/staticdifferential/main.nf | 4 +-- .../tests/main.nf.test.snap | 18 +++++------ .../staticexploratory/environment.yml | 2 +- .../shinyngs/staticexploratory/main.nf | 4 +-- .../staticexploratory/tests/main.nf.test.snap | 32 +++++++++---------- .../validatefomcomponents/environment.yml | 2 +- .../shinyngs/validatefomcomponents/main.nf | 4 +-- .../tests/main.nf.test.snap | 30 ++++++++--------- 12 files changed, 64 insertions(+), 64 deletions(-) diff --git a/modules/nf-core/shinyngs/app/environment.yml b/modules/nf-core/shinyngs/app/environment.yml index 3e9cc201b770..445fed3ca21b 100644 --- a/modules/nf-core/shinyngs/app/environment.yml +++ b/modules/nf-core/shinyngs/app/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::r-shinyngs=2.2.4 + - bioconda::r-shinyngs=2.3.0 diff --git a/modules/nf-core/shinyngs/app/main.nf b/modules/nf-core/shinyngs/app/main.nf index 2e956ad6c2bc..65b32f819f66 100644 --- a/modules/nf-core/shinyngs/app/main.nf +++ b/modules/nf-core/shinyngs/app/main.nf @@ -14,8 +14,8 @@ process SHINYNGS_APP { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/4f/4fc080dc45831489dd70b8183314a5a6f840064d6c78f3466790df0fba1503d0/data' : - 'community.wave.seqera.io/library/r-shinyngs:2.2.4--2bf759f8be585e75' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/d0/d0937af0a2b5efe1c18565ef320956e630a03c00c6d75ea5df92ec9f9ff2d14e/data' : + 'community.wave.seqera.io/library/r-shinyngs:2.3.0--140cda6231347fbb' }" input: tuple val(meta), path(sample), path(feature_meta), path(assay_files) // Experiment-level info diff --git a/modules/nf-core/shinyngs/app/tests/main.nf.test.snap b/modules/nf-core/shinyngs/app/tests/main.nf.test.snap index ba39909e29b1..c7d75089a22d 100644 --- a/modules/nf-core/shinyngs/app/tests/main.nf.test.snap +++ b/modules/nf-core/shinyngs/app/tests/main.nf.test.snap @@ -4,41 +4,41 @@ "data.rds", "app.R:md5,d41d8cd98f00b204e9800998ecf8427e", [ - "versions.yml:md5,a7165231603c3f0675568989e1c16c36" + "versions.yml:md5,01db56d3cdd2e134e65df5465ea4eb0c" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-02T16:42:06.649371488" + "timestamp": "2025-12-01T17:45:00.111194977" }, "mouse - multi matrix": { "content": [ "data.rds", "app.R:md5,bedcfc45b6cdcc2b8fe3627987e2b17a", [ - "versions.yml:md5,a7165231603c3f0675568989e1c16c36" + "versions.yml:md5,01db56d3cdd2e134e65df5465ea4eb0c" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-02T16:41:14.463468708" + "timestamp": "2025-12-01T17:44:28.229851192" }, "mouse - single matrix": { "content": [ "data.rds", "app.R:md5,bedcfc45b6cdcc2b8fe3627987e2b17a", [ - "versions.yml:md5,a7165231603c3f0675568989e1c16c36" + "versions.yml:md5,01db56d3cdd2e134e65df5465ea4eb0c" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-02T16:41:43.718285268" + "timestamp": "2025-12-01T17:44:47.274942197" } } \ No newline at end of file diff --git a/modules/nf-core/shinyngs/staticdifferential/environment.yml b/modules/nf-core/shinyngs/staticdifferential/environment.yml index 3e9cc201b770..445fed3ca21b 100644 --- a/modules/nf-core/shinyngs/staticdifferential/environment.yml +++ b/modules/nf-core/shinyngs/staticdifferential/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::r-shinyngs=2.2.4 + - bioconda::r-shinyngs=2.3.0 diff --git a/modules/nf-core/shinyngs/staticdifferential/main.nf b/modules/nf-core/shinyngs/staticdifferential/main.nf index 06f040ba1f26..44995ea4296a 100644 --- a/modules/nf-core/shinyngs/staticdifferential/main.nf +++ b/modules/nf-core/shinyngs/staticdifferential/main.nf @@ -4,8 +4,8 @@ process SHINYNGS_STATICDIFFERENTIAL { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/4f/4fc080dc45831489dd70b8183314a5a6f840064d6c78f3466790df0fba1503d0/data' : - 'community.wave.seqera.io/library/r-shinyngs:2.2.4--2bf759f8be585e75' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/d0/d0937af0a2b5efe1c18565ef320956e630a03c00c6d75ea5df92ec9f9ff2d14e/data' : + 'community.wave.seqera.io/library/r-shinyngs:2.3.0--140cda6231347fbb' }" input: tuple val(meta), path(differential_result) // Differential info: contrast and differential stats diff --git a/modules/nf-core/shinyngs/staticdifferential/tests/main.nf.test.snap b/modules/nf-core/shinyngs/staticdifferential/tests/main.nf.test.snap index fc72a836471e..22d2c20edb21 100644 --- a/modules/nf-core/shinyngs/staticdifferential/tests/main.nf.test.snap +++ b/modules/nf-core/shinyngs/staticdifferential/tests/main.nf.test.snap @@ -6,14 +6,14 @@ ], [ - "versions.yml:md5,b354e83a028f5c38cf61821a927a92d7" + "versions.yml:md5,a71d1d5f6a15f9fefd34ca0ada81842b" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-02T16:42:43.682019774" + "timestamp": "2025-12-01T17:45:23.17214359" }, "stub": { "content": [ @@ -43,10 +43,10 @@ ] ], "2": [ - "versions.yml:md5,b354e83a028f5c38cf61821a927a92d7" + "versions.yml:md5,a71d1d5f6a15f9fefd34ca0ada81842b" ], "versions": [ - "versions.yml:md5,b354e83a028f5c38cf61821a927a92d7" + "versions.yml:md5,a71d1d5f6a15f9fefd34ca0ada81842b" ], "volcanos_html": [ [ @@ -75,9 +75,9 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-02T16:43:05.46187287" + "timestamp": "2025-12-01T17:45:36.887175944" } } \ No newline at end of file diff --git a/modules/nf-core/shinyngs/staticexploratory/environment.yml b/modules/nf-core/shinyngs/staticexploratory/environment.yml index 3e9cc201b770..445fed3ca21b 100644 --- a/modules/nf-core/shinyngs/staticexploratory/environment.yml +++ b/modules/nf-core/shinyngs/staticexploratory/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::r-shinyngs=2.2.4 + - bioconda::r-shinyngs=2.3.0 diff --git a/modules/nf-core/shinyngs/staticexploratory/main.nf b/modules/nf-core/shinyngs/staticexploratory/main.nf index 7cc096ae7c04..6819d05afd63 100644 --- a/modules/nf-core/shinyngs/staticexploratory/main.nf +++ b/modules/nf-core/shinyngs/staticexploratory/main.nf @@ -4,8 +4,8 @@ process SHINYNGS_STATICEXPLORATORY { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/4f/4fc080dc45831489dd70b8183314a5a6f840064d6c78f3466790df0fba1503d0/data' : - 'community.wave.seqera.io/library/r-shinyngs:2.2.4--2bf759f8be585e75' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/d0/d0937af0a2b5efe1c18565ef320956e630a03c00c6d75ea5df92ec9f9ff2d14e/data' : + 'community.wave.seqera.io/library/r-shinyngs:2.3.0--140cda6231347fbb' }" input: tuple val(meta), path(sample), path(feature_meta), path(assay_files), val(variable) diff --git a/modules/nf-core/shinyngs/staticexploratory/tests/main.nf.test.snap b/modules/nf-core/shinyngs/staticexploratory/tests/main.nf.test.snap index db0426babf6c..4f11d0f72470 100644 --- a/modules/nf-core/shinyngs/staticexploratory/tests/main.nf.test.snap +++ b/modules/nf-core/shinyngs/staticexploratory/tests/main.nf.test.snap @@ -8,14 +8,14 @@ "pca3d.png", "sample_dendrogram.png", [ - "versions.yml:md5,ccb51082df7cfed8fad43e1bbaf6dc63" + "versions.yml:md5,91989cb95f99f7921bf93946d2e9131c" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-02T16:37:50.314588599" + "timestamp": "2025-12-01T17:46:11.289150469" }, "mouse - defaults": { "content": [ @@ -26,14 +26,14 @@ "pca3d.png", "sample_dendrogram.png", [ - "versions.yml:md5,ccb51082df7cfed8fad43e1bbaf6dc63" + "versions.yml:md5,91989cb95f99f7921bf93946d2e9131c" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-02T16:37:32.399343012" + "timestamp": "2025-12-01T17:45:58.516740998" }, "mouse - specify log": { "content": [ @@ -44,14 +44,14 @@ "pca3d.png", "sample_dendrogram.png", [ - "versions.yml:md5,ccb51082df7cfed8fad43e1bbaf6dc63" + "versions.yml:md5,91989cb95f99f7921bf93946d2e9131c" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-02T16:38:16.545811656" + "timestamp": "2025-12-01T17:46:32.257225071" }, "mouse - html": { "content": [ @@ -67,13 +67,13 @@ false, false, [ - "versions.yml:md5,ccb51082df7cfed8fad43e1bbaf6dc63" + "versions.yml:md5,91989cb95f99f7921bf93946d2e9131c" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-02T16:38:44.838937428" + "timestamp": "2025-12-01T17:46:55.235470561" } } \ No newline at end of file diff --git a/modules/nf-core/shinyngs/validatefomcomponents/environment.yml b/modules/nf-core/shinyngs/validatefomcomponents/environment.yml index 3e9cc201b770..445fed3ca21b 100644 --- a/modules/nf-core/shinyngs/validatefomcomponents/environment.yml +++ b/modules/nf-core/shinyngs/validatefomcomponents/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::r-shinyngs=2.2.4 + - bioconda::r-shinyngs=2.3.0 diff --git a/modules/nf-core/shinyngs/validatefomcomponents/main.nf b/modules/nf-core/shinyngs/validatefomcomponents/main.nf index 78990f53cbda..fed28dc96fa8 100644 --- a/modules/nf-core/shinyngs/validatefomcomponents/main.nf +++ b/modules/nf-core/shinyngs/validatefomcomponents/main.nf @@ -4,8 +4,8 @@ process SHINYNGS_VALIDATEFOMCOMPONENTS { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/4f/4fc080dc45831489dd70b8183314a5a6f840064d6c78f3466790df0fba1503d0/data' : - 'community.wave.seqera.io/library/r-shinyngs:2.2.4--2bf759f8be585e75' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/d0/d0937af0a2b5efe1c18565ef320956e630a03c00c6d75ea5df92ec9f9ff2d14e/data' : + 'community.wave.seqera.io/library/r-shinyngs:2.3.0--140cda6231347fbb' }" input: tuple val(meta), path(sample), path(assay_files) diff --git a/modules/nf-core/shinyngs/validatefomcomponents/tests/main.nf.test.snap b/modules/nf-core/shinyngs/validatefomcomponents/tests/main.nf.test.snap index a3ba5f19bf53..3ca81fb269c2 100644 --- a/modules/nf-core/shinyngs/validatefomcomponents/tests/main.nf.test.snap +++ b/modules/nf-core/shinyngs/validatefomcomponents/tests/main.nf.test.snap @@ -35,7 +35,7 @@ ] ], "4": [ - "versions.yml:md5,07717fd9910caccc6b6606da92af59e6" + "versions.yml:md5,27b6e705643da7c923f338abb7e84dbb" ], "assays": [ [ @@ -70,15 +70,15 @@ ] ], "versions": [ - "versions.yml:md5,07717fd9910caccc6b6606da92af59e6" + "versions.yml:md5,27b6e705643da7c923f338abb7e84dbb" ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-02T16:34:37.174853667" + "timestamp": "2025-12-01T17:47:16.763658341" }, "stub": { "content": [ @@ -116,7 +116,7 @@ ] ], "4": [ - "versions.yml:md5,07717fd9910caccc6b6606da92af59e6" + "versions.yml:md5,27b6e705643da7c923f338abb7e84dbb" ], "assays": [ [ @@ -151,15 +151,15 @@ ] ], "versions": [ - "versions.yml:md5,07717fd9910caccc6b6606da92af59e6" + "versions.yml:md5,27b6e705643da7c923f338abb7e84dbb" ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-02T16:35:23.600562533" + "timestamp": "2025-12-01T17:47:52.072518885" }, "test_yaml": { "content": [ @@ -197,7 +197,7 @@ ] ], "4": [ - "versions.yml:md5,07717fd9910caccc6b6606da92af59e6" + "versions.yml:md5,27b6e705643da7c923f338abb7e84dbb" ], "assays": [ [ @@ -232,14 +232,14 @@ ] ], "versions": [ - "versions.yml:md5,07717fd9910caccc6b6606da92af59e6" + "versions.yml:md5,27b6e705643da7c923f338abb7e84dbb" ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-02T16:35:04.455614097" + "timestamp": "2025-12-01T17:47:38.315342815" } } \ No newline at end of file From 71307745e4f6efef1963ac58d2d4ccd7456b2c2a Mon Sep 17 00:00:00 2001 From: "Diego Alvarez S." Date: Tue, 2 Dec 2025 13:31:42 -0300 Subject: [PATCH 09/83] Update semibin/singleeasybin environment (#9495) --- .../nf-core/semibin/singleeasybin/environment.yml | 3 +++ modules/nf-core/semibin/singleeasybin/main.nf | 4 ++-- .../semibin/singleeasybin/tests/main.nf.test.snap | 14 +++++++------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/modules/nf-core/semibin/singleeasybin/environment.yml b/modules/nf-core/semibin/singleeasybin/environment.yml index 20654bc963ba..ae3654fbbd6d 100644 --- a/modules/nf-core/semibin/singleeasybin/environment.yml +++ b/modules/nf-core/semibin/singleeasybin/environment.yml @@ -5,3 +5,6 @@ channels: - bioconda dependencies: - bioconda::semibin=2.2.0 + # This pins solves an issue of SemiBin getting stuck. + # See https://github.com/BigDataBiology/SemiBin/issues/208 + - conda-forge::igraph=0.10.17 diff --git a/modules/nf-core/semibin/singleeasybin/main.nf b/modules/nf-core/semibin/singleeasybin/main.nf index 76b1a6ac2252..913ddefa8b68 100644 --- a/modules/nf-core/semibin/singleeasybin/main.nf +++ b/modules/nf-core/semibin/singleeasybin/main.nf @@ -4,8 +4,8 @@ process SEMIBIN_SINGLEEASYBIN { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/semibin:2.2.0--pyhdfd78af_0': - 'biocontainers/semibin:2.2.0--pyhdfd78af_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/0d/0d205dadfeb5d37829b4fbde39319b07e2971884670ff7e84df4cc4d809ff8a5/data': + 'community.wave.seqera.io/library/semibin_igraph:fcb667d6c87bf3fd' }" input: tuple val(meta), path(fasta), path(bam) diff --git a/modules/nf-core/semibin/singleeasybin/tests/main.nf.test.snap b/modules/nf-core/semibin/singleeasybin/tests/main.nf.test.snap index 61ed620ee72a..affadd0ef7bc 100644 --- a/modules/nf-core/semibin/singleeasybin/tests/main.nf.test.snap +++ b/modules/nf-core/semibin/singleeasybin/tests/main.nf.test.snap @@ -8,9 +8,9 @@ "id": "test" }, [ - "data.csv:md5,afdbb1c4a8c64aa1411c14521615a38a", + "data.csv:md5,eff24dad52ab76b8a030335c938a64f6", "data_split.csv:md5,6f05c805f4e696315d104de6cc0c8f23", - "test1_contigs.sorted.bam_0_data_cov.csv:md5,85e1f6ca7e56c717700fbf5773dcf3c4" + "test1_contigs.sorted.bam_0_data_cov.csv:md5,fd0978a81966ee7c817dfeff79d082ae" ] ] ], @@ -74,9 +74,9 @@ "id": "test" }, [ - "data.csv:md5,afdbb1c4a8c64aa1411c14521615a38a", + "data.csv:md5,eff24dad52ab76b8a030335c938a64f6", "data_split.csv:md5,6f05c805f4e696315d104de6cc0c8f23", - "test1_contigs.sorted.bam_0_data_cov.csv:md5,85e1f6ca7e56c717700fbf5773dcf3c4" + "test1_contigs.sorted.bam_0_data_cov.csv:md5,fd0978a81966ee7c817dfeff79d082ae" ] ] ], @@ -142,10 +142,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-05-09T08:17:02.965125107" + "timestamp": "2025-12-02T13:19:13.461592294" }, "bacteroides_fragilis - stub": { "content": [ From e188efd511c17386aa02704f467c1490e1e34f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Wed, 3 Dec 2025 09:27:54 +0100 Subject: [PATCH 10/83] add new ontology term to tcoffee align (#9497) --- modules/nf-core/tcoffee/align/meta.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/nf-core/tcoffee/align/meta.yml b/modules/nf-core/tcoffee/align/meta.yml index e38b25d9c596..a69bb71b08b5 100644 --- a/modules/nf-core/tcoffee/align/meta.yml +++ b/modules/nf-core/tcoffee/align/meta.yml @@ -60,6 +60,7 @@ input: be protein structures or secondary structures. ontologies: - edam: http://edamontology.org/format_1476 # PDB + - edam: http://edamontology.org/format_1477 # mmCIF - compress: type: boolean description: Flag representing whether the output MSA should be compressed. Set From 74834d86cda19ffc866b61ac07f9f1ad6ec9be80 Mon Sep 17 00:00:00 2001 From: Nathan Weeks <1800812+nathanweeks@users.noreply.github.com> Date: Wed, 3 Dec 2025 09:14:57 -0500 Subject: [PATCH 11/83] tcoffee_extractfrompdb test: sort file listing so "first" file is deterministic (#9489) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Sort file listing so "first" file is deterministic * Declare closure parameter per strict syntax Co-authored-by: Matthias Hörtenhuber --------- Co-authored-by: Matthias Hörtenhuber Co-authored-by: mashehu --- modules/nf-core/tcoffee/extractfrompdb/tests/main.nf.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nf-core/tcoffee/extractfrompdb/tests/main.nf.test b/modules/nf-core/tcoffee/extractfrompdb/tests/main.nf.test index c0b4405e4131..71686235246b 100644 --- a/modules/nf-core/tcoffee/extractfrompdb/tests/main.nf.test +++ b/modules/nf-core/tcoffee/extractfrompdb/tests/main.nf.test @@ -28,7 +28,7 @@ nextflow_process { when { process { """ - input[0] = UNTAR.out.untar.collect{ meta, dir -> file(dir).listFiles().collect().first() }.map{ pdb -> [[ id: 'test'], pdb]} + input[0] = UNTAR.out.untar.collect{ meta, dir -> file(dir).listFiles().toList().sort{ file -> file.name }.first() }.map{ pdb -> [[ id: 'test'], pdb]} """ } } From f69fa149324bb50d7020dd33661d36f3675a9fbd Mon Sep 17 00:00:00 2001 From: Peter Pruisscher <57712924+peterpru@users.noreply.github.com> Date: Wed, 3 Dec 2025 16:42:05 +0100 Subject: [PATCH 12/83] Sambamba depth add region bed input (#9498) * sambamba add region bed input * fix linting * fix linting * Apply suggestions from code review Co-authored-by: Felix Lenner <52530259+fellen31@users.noreply.github.com> --------- Co-authored-by: Felix Lenner <52530259+fellen31@users.noreply.github.com> --- modules/nf-core/sambamba/depth/main.nf | 3 ++ modules/nf-core/sambamba/depth/meta.yml | 10 +++++ .../nf-core/sambamba/depth/tests/main.nf.test | 33 +++++++++++++- .../sambamba/depth/tests/main.nf.test.snap | 43 +++++++++++++++++-- 4 files changed, 83 insertions(+), 6 deletions(-) diff --git a/modules/nf-core/sambamba/depth/main.nf b/modules/nf-core/sambamba/depth/main.nf index 5639f5bf1f04..e1404c7b0dba 100644 --- a/modules/nf-core/sambamba/depth/main.nf +++ b/modules/nf-core/sambamba/depth/main.nf @@ -9,6 +9,7 @@ process SAMBAMBA_DEPTH { input: tuple val(meta), path(bam), path(bai) + tuple val(meta2), path(bed) val(mode) output: @@ -24,11 +25,13 @@ process SAMBAMBA_DEPTH { if (!['region','window','base'].contains(mode)) { error "Mode needs to be one of: region, window, base" } + def bed_arg = bed ? "--regions ${bed}" : '' """ sambamba \\ depth \\ $mode \\ + $bed_arg \\ $args \\ -t $task.cpus \\ -o ${prefix}.bed \\ diff --git a/modules/nf-core/sambamba/depth/meta.yml b/modules/nf-core/sambamba/depth/meta.yml index 677fe3d6cbf1..c16ce3a72f85 100644 --- a/modules/nf-core/sambamba/depth/meta.yml +++ b/modules/nf-core/sambamba/depth/meta.yml @@ -32,6 +32,16 @@ input: pattern: "*.{bai}" ontologies: - edam: "http://edamontology.org/format_2572" + - - meta2: + type: map + description: | + Groovy Map containing regions information + - bed: + type: file + description: bed file + pattern: "*.{bed}" + ontologies: + - edam: "http://edamontology.org/format_3003" # BED - mode: type: string description: Analysis mode can be region, window, base diff --git a/modules/nf-core/sambamba/depth/tests/main.nf.test b/modules/nf-core/sambamba/depth/tests/main.nf.test index 1591ded2b414..3f51059861b7 100644 --- a/modules/nf-core/sambamba/depth/tests/main.nf.test +++ b/modules/nf-core/sambamba/depth/tests/main.nf.test @@ -20,7 +20,8 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) ] - input[1] = 'base' + input[1] = [[], []] + input[2] = 'base' """ } @@ -34,6 +35,33 @@ nextflow_process { } } + test("test-sambamba-depth-with-region-bed") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [ + [ id:'test2' ], // meta2 map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true) + ] + input[2] = 'region' + + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } test("test-sambamba-depth-stub") { @@ -47,7 +75,8 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) ] - input[1] = 'base' + input[1] = [[], []] + input[2] = 'base' """ } diff --git a/modules/nf-core/sambamba/depth/tests/main.nf.test.snap b/modules/nf-core/sambamba/depth/tests/main.nf.test.snap index 38378f20e129..7f4951e62acb 100644 --- a/modules/nf-core/sambamba/depth/tests/main.nf.test.snap +++ b/modules/nf-core/sambamba/depth/tests/main.nf.test.snap @@ -1,4 +1,39 @@ { + "test-sambamba-depth-with-region-bed": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,e312edd2c0a9f63b833b5a8913952ba6" + ] + ], + "1": [ + "versions.yml:md5,6e2f38cc3306b1ea59da275d9de28d57" + ], + "bed": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,e312edd2c0a9f63b833b5a8913952ba6" + ] + ], + "versions": [ + "versions.yml:md5,6e2f38cc3306b1ea59da275d9de28d57" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-03T15:57:58.097957" + }, "test-sambamba-depth": { "content": [ { @@ -29,10 +64,10 @@ } ], "meta": { - "nf-test": "0.9.2", + "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-12T15:12:13.586918" + "timestamp": "2025-12-03T15:57:42.031913" }, "test-sambamba-depth-stub": { "content": [ @@ -64,9 +99,9 @@ } ], "meta": { - "nf-test": "0.9.2", + "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-12T15:12:29.380779" + "timestamp": "2025-12-03T15:58:13.647811" } } \ No newline at end of file From 2629da3687299a354415413fbd329860ef491b45 Mon Sep 17 00:00:00 2001 From: Sateesh_Peri <33637490+sateeshperi@users.noreply.github.com> Date: Wed, 3 Dec 2025 21:33:37 +0530 Subject: [PATCH 13/83] fix fasta_index_methylseq and fastq_align_dedup workflows (#9496) * fix fasta_index_methylseq and fastq_align_dedup workflows for clarity and consistency - Updated variable names in fasta_index_methylseq to use 'channel' instead of 'Channel' for consistency. - Renamed UNTAR to UNTAR_BISMARK and UNTAR_BWAMETH for clarity in fasta_index_methylseq. - Enhanced comments and descriptions in meta.yml files for better understanding of input and output structures. - Adjusted test cases in fastq_align_dedup workflows to reflect changes in input structure from single-end to paired-end. - Updated version numbers in test snapshots to reflect recent changes. * fix: pre-commit lint fixes --- .../nf-core/fasta_index_methylseq/main.nf | 72 +++-- .../nf-core/fasta_index_methylseq/meta.yml | 2 +- .../tests/main.nf.test.snap | 78 ++--- .../nf-core/fastq_align_dedup_bismark/main.nf | 48 +-- .../fastq_align_dedup_bismark/meta.yml | 6 +- .../tests/main.nf.test | 48 +-- .../tests/main.nf.test.snap | 300 +++++++++--------- .../nf-core/fastq_align_dedup_bwamem/main.nf | 64 ++-- .../nf-core/fastq_align_dedup_bwamem/meta.yml | 6 +- .../tests/main.nf.test | 14 +- .../tests/main.nf.test.snap | 159 ++-------- .../nf-core/fastq_align_dedup_bwameth/main.nf | 35 +- .../fastq_align_dedup_bwameth/meta.yml | 6 +- .../tests/main.nf.test | 4 +- .../tests/main.nf.test.snap | 12 +- 15 files changed, 373 insertions(+), 481 deletions(-) diff --git a/subworkflows/nf-core/fasta_index_methylseq/main.nf b/subworkflows/nf-core/fasta_index_methylseq/main.nf index e0a7c5db44c8..4c74bc5555d8 100644 --- a/subworkflows/nf-core/fasta_index_methylseq/main.nf +++ b/subworkflows/nf-core/fasta_index_methylseq/main.nf @@ -1,4 +1,5 @@ -include { UNTAR } from '../../../modules/nf-core/untar/main' +include { UNTAR as UNTAR_BISMARK } from '../../../modules/nf-core/untar/main' +include { UNTAR as UNTAR_BWAMETH } from '../../../modules/nf-core/untar/main' include { GUNZIP } from '../../../modules/nf-core/gunzip/main' include { BISMARK_GENOMEPREPARATION as BISMARK_GENOMEPREPARATION_BOWTIE } from '../../../modules/nf-core/bismark/genomepreparation/main' include { BISMARK_GENOMEPREPARATION as BISMARK_GENOMEPREPARATION_HISAT } from '../../../modules/nf-core/bismark/genomepreparation/main' @@ -14,18 +15,18 @@ workflow FASTA_INDEX_METHYLSEQ { bismark_index // channel: [ val(meta), [ bismark index ] ] bwameth_index // channel: [ val(meta), [ bwameth index ] ] bwamem_index // channel: [ val(meta), [ bwamem index ] ] - aligner // string: bismark, bismark_hisat or bwameth + aligner // string: bismark, bismark_hisat, bwameth or bwamem collecthsmetrics // boolean: whether to run picard collecthsmetrics use_mem2 // boolean: generate mem2 index if no index provided, and bwameth is selected main: - ch_fasta = Channel.empty() - ch_fasta_index = Channel.empty() - ch_bismark_index = Channel.empty() - ch_bwameth_index = Channel.empty() - ch_bwamem_index = Channel.empty() - ch_versions = Channel.empty() + ch_fasta = channel.empty() + ch_fasta_index = channel.empty() + ch_bismark_index = channel.empty() + ch_bwameth_index = channel.empty() + ch_bwamem_index = channel.empty() + ch_versions = channel.empty() // Check if fasta file is gzipped and decompress if needed fasta @@ -56,17 +57,17 @@ workflow FASTA_INDEX_METHYLSEQ { } .set { ch_bismark_index_branched } - UNTAR ( + UNTAR_BISMARK ( ch_bismark_index_branched.gzipped ) - ch_bismark_index = ch_bismark_index_branched.unzipped.mix(UNTAR.out.untar) - ch_versions = ch_versions.mix(UNTAR.out.versions) + ch_bismark_index = ch_bismark_index_branched.unzipped.mix(UNTAR_BISMARK.out.untar) + ch_versions = ch_versions.mix(UNTAR_BISMARK.out.versions) } else { if( aligner == "bismark_hisat") { BISMARK_GENOMEPREPARATION_HISAT ( - ch_fasta + ch_fasta ) ch_bismark_index = BISMARK_GENOMEPREPARATION_HISAT.out.index ch_versions = ch_versions.mix(BISMARK_GENOMEPREPARATION_HISAT.out.versions) @@ -94,24 +95,17 @@ workflow FASTA_INDEX_METHYLSEQ { } .set { ch_bwameth_index_branched } - UNTAR ( + UNTAR_BWAMETH ( ch_bwameth_index_branched.gzipped ) - ch_bwameth_index = ch_bwameth_index_branched.unzipped.mix(UNTAR.out.untar) - ch_versions = ch_versions.mix(UNTAR.out.versions) + ch_bwameth_index = ch_bwameth_index_branched.unzipped.mix(UNTAR_BWAMETH.out.untar) + ch_versions = ch_versions.mix(UNTAR_BWAMETH.out.versions) } else { - if (use_mem2) { - BWAMETH_INDEX ( - ch_fasta, - true - ) - } else { - BWAMETH_INDEX ( - ch_fasta, - false - ) - } + BWAMETH_INDEX ( + ch_fasta, + use_mem2 + ) ch_bwameth_index = BWAMETH_INDEX.out.index ch_versions = ch_versions.mix(BWAMETH_INDEX.out.versions) } @@ -119,14 +113,27 @@ workflow FASTA_INDEX_METHYLSEQ { else if ( aligner == 'bwamem' ){ - log.info "BWA index not provided. Generating BWA index from FASTA file." /* * Generate BWA index from FASTA file */ if (bwamem_index) { - ch_bwamem_index = bwamem_index + // Handle channel-based bwamem index + bwamem_index + .branch { + gzipped: it[1].toString().endsWith('.gz') + unzipped: true + } + .set { ch_bwamem_index_branched } + + UNTAR_BISMARK ( + ch_bwamem_index_branched.gzipped + ) + + ch_bwamem_index = ch_bwamem_index_branched.unzipped.mix(UNTAR_BISMARK.out.untar) + ch_versions = ch_versions.mix(UNTAR_BISMARK.out.versions) } else { - BWA_INDEX( + log.info "BWA index not provided. Generating BWA index from FASTA file." + BWA_INDEX ( ch_fasta ) ch_bwamem_index = BWA_INDEX.out.index @@ -138,11 +145,12 @@ workflow FASTA_INDEX_METHYLSEQ { * Generate fasta index if not supplied for bwameth workflow or picard collecthsmetrics tool */ if (aligner == 'bwameth' || aligner == 'bwamem' || collecthsmetrics) { - // already exising fasta index + // already existing fasta index if (fasta_index) { ch_fasta_index = fasta_index } else { - SAMTOOLS_FAIDX( + log.info "Fasta index not provided. Generating fasta index from FASTA file." + SAMTOOLS_FAIDX ( ch_fasta, [[:], []], false @@ -157,6 +165,6 @@ workflow FASTA_INDEX_METHYLSEQ { fasta_index = ch_fasta_index // channel: [ val(meta), [ fasta index ] ] bismark_index = ch_bismark_index // channel: [ val(meta), [ bismark index ] ] bwameth_index = ch_bwameth_index // channel: [ val(meta), [ bwameth index ] ] - bwamem_index = ch_bwamem_index // channel: [ val(meta), [ bwamem index ] ] + bwamem_index = ch_bwamem_index // channel: [ val(meta), [ bwamem index ] ] versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/fasta_index_methylseq/meta.yml b/subworkflows/nf-core/fasta_index_methylseq/meta.yml index cffb6cb3a39f..db17e814870c 100644 --- a/subworkflows/nf-core/fasta_index_methylseq/meta.yml +++ b/subworkflows/nf-core/fasta_index_methylseq/meta.yml @@ -45,7 +45,7 @@ input: - aligner: type: string description: | - Aligner name (bismark, bismark_hisat, or bwameth) + Aligner name (bismark, bismark_hisat, bwameth, or bwamem) - collecthsmetrics: type: boolean description: | diff --git a/subworkflows/nf-core/fasta_index_methylseq/tests/main.nf.test.snap b/subworkflows/nf-core/fasta_index_methylseq/tests/main.nf.test.snap index 96e487025fff..413870ba11ce 100644 --- a/subworkflows/nf-core/fasta_index_methylseq/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fasta_index_methylseq/tests/main.nf.test.snap @@ -90,15 +90,15 @@ ], [ "versions.yml:md5,1a7e59286a0e918ba2400750ddefd444", - "versions.yml:md5,80527e72159961c33cd9a6d4847e75e3", + "versions.yml:md5,51df3ff0a3067a7a676cdc4e4d237a69", "versions.yml:md5,8afe74b43d9155c93e27ae1b36a7ae97" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-30T10:54:41.408759009" + "timestamp": "2025-12-03T12:20:26.495603" }, "Params: bwameth | generate fasta index | download bwameth index | collecthsmetrics": { "content": [ @@ -142,15 +142,15 @@ ], [ "versions.yml:md5,1a7e59286a0e918ba2400750ddefd444", - "versions.yml:md5,80527e72159961c33cd9a6d4847e75e3", + "versions.yml:md5,51df3ff0a3067a7a676cdc4e4d237a69", "versions.yml:md5,8afe74b43d9155c93e27ae1b36a7ae97" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-30T10:55:10.001932564" + "timestamp": "2025-12-03T12:21:13.279634" }, "Params: bwameth | generate fasta index | generate bwameth mem2 index": { "content": [ @@ -253,15 +253,15 @@ ], [ - "versions.yml:md5,80527e72159961c33cd9a6d4847e75e3", - "versions.yml:md5,8afe74b43d9155c93e27ae1b36a7ae97" + "versions.yml:md5,8afe74b43d9155c93e27ae1b36a7ae97", + "versions.yml:md5,d3ed85f31ec769229e17780530e235ee" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-30T10:53:57.304989914" + "timestamp": "2025-12-03T12:19:16.006311" }, "Params: bwameth | generate fasta index | download bwameth mem2 index | collecthsmetrics": { "content": [ @@ -304,15 +304,15 @@ ], [ "versions.yml:md5,1a7e59286a0e918ba2400750ddefd444", - "versions.yml:md5,80527e72159961c33cd9a6d4847e75e3", + "versions.yml:md5,51df3ff0a3067a7a676cdc4e4d237a69", "versions.yml:md5,8afe74b43d9155c93e27ae1b36a7ae97" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-30T10:55:16.817726661" + "timestamp": "2025-12-03T12:21:24.368005" }, "Params: bwameth | generate fasta index | download bwameth mem2 index": { "content": [ @@ -355,15 +355,15 @@ ], [ "versions.yml:md5,1a7e59286a0e918ba2400750ddefd444", - "versions.yml:md5,80527e72159961c33cd9a6d4847e75e3", + "versions.yml:md5,51df3ff0a3067a7a676cdc4e4d237a69", "versions.yml:md5,8afe74b43d9155c93e27ae1b36a7ae97" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-30T10:54:48.244071885" + "timestamp": "2025-12-03T12:20:37.640088" }, "Params: bwameth | generate fasta index | generate bwameth index": { "content": [ @@ -470,15 +470,15 @@ ], [ - "versions.yml:md5,80527e72159961c33cd9a6d4847e75e3", - "versions.yml:md5,8afe74b43d9155c93e27ae1b36a7ae97" + "versions.yml:md5,8afe74b43d9155c93e27ae1b36a7ae97", + "versions.yml:md5,d3ed85f31ec769229e17780530e235ee" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-30T10:54:21.879254265" + "timestamp": "2025-12-03T12:19:53.905574" }, "Params: bismark_hisat | download bismark index (hisat2)": { "content": [ @@ -534,15 +534,15 @@ ], [ - "versions.yml:md5,80527e72159961c33cd9a6d4847e75e3", - "versions.yml:md5,8afe74b43d9155c93e27ae1b36a7ae97" + "versions.yml:md5,8afe74b43d9155c93e27ae1b36a7ae97", + "versions.yml:md5,d3ed85f31ec769229e17780530e235ee" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-30T10:54:15.523551748" + "timestamp": "2025-12-03T12:19:42.978899" }, "Params: bwameth | download fasta index | download bwameth index": { "content": [ @@ -585,15 +585,15 @@ ], [ - "versions.yml:md5,80527e72159961c33cd9a6d4847e75e3", + "versions.yml:md5,51df3ff0a3067a7a676cdc4e4d237a69", "versions.yml:md5,8afe74b43d9155c93e27ae1b36a7ae97" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-30T10:54:28.152242843" + "timestamp": "2025-12-03T12:20:04.798139" }, "Params: bwameth | download fasta index | download bwameth mem2 index": { "content": [ @@ -635,15 +635,15 @@ ], [ - "versions.yml:md5,80527e72159961c33cd9a6d4847e75e3", + "versions.yml:md5,51df3ff0a3067a7a676cdc4e4d237a69", "versions.yml:md5,8afe74b43d9155c93e27ae1b36a7ae97" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-30T10:54:34.434835743" + "timestamp": "2025-12-03T12:20:15.282566" }, "Params: bwamem | generate fasta index | generate bwamem index": { "content": [ diff --git a/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf b/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf index 03f2ff5a81d6..c08686cb542f 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf +++ b/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf @@ -17,20 +17,20 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { cytosine_report // boolean: whether the run coverage2cytosine main: - ch_alignments = Channel.empty() - ch_alignment_reports = Channel.empty() - ch_methylation_bedgraph = Channel.empty() - ch_methylation_calls = Channel.empty() - ch_methylation_coverage = Channel.empty() - ch_methylation_report = Channel.empty() - ch_methylation_mbias = Channel.empty() - ch_coverage2cytosine_coverage = Channel.empty() - ch_coverage2cytosine_report = Channel.empty() - ch_coverage2cytosine_summary = Channel.empty() - ch_bismark_report = Channel.empty() - ch_bismark_summary = Channel.empty() - ch_multiqc_files = Channel.empty() - ch_versions = Channel.empty() + ch_alignments = channel.empty() + ch_alignment_reports = channel.empty() + ch_methylation_bedgraph = channel.empty() + ch_methylation_calls = channel.empty() + ch_methylation_coverage = channel.empty() + ch_methylation_report = channel.empty() + ch_methylation_mbias = channel.empty() + ch_coverage2cytosine_coverage = channel.empty() + ch_coverage2cytosine_report = channel.empty() + ch_coverage2cytosine_summary = channel.empty() + ch_bismark_report = channel.empty() + ch_bismark_summary = channel.empty() + ch_multiqc_files = channel.empty() + ch_versions = channel.empty() /* * Align with bismark @@ -116,11 +116,11 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { * Generate bismark summary report */ BISMARK_SUMMARY ( - BISMARK_ALIGN.out.bam.collect{ meta, bam -> bam.name }, - ch_alignment_reports.collect{ meta, align_report, dedup_report -> align_report }, - ch_alignment_reports.collect{ meta, align_report, dedup_report -> dedup_report }.ifEmpty([]), - ch_methylation_report.collect{ meta, report -> report }, - ch_methylation_mbias.collect{ meta, mbias -> mbias } + BISMARK_ALIGN.out.bam.collect{ _meta, bam -> bam.name }, + ch_alignment_reports.collect{ _meta, align_report, _dedup_report -> align_report }, + ch_alignment_reports.collect{ _meta, _align_report, dedup_report -> dedup_report }.ifEmpty([]), + ch_methylation_report.collect{ _meta, report -> report }, + ch_methylation_mbias.collect{ _meta, mbias -> mbias } ) ch_bismark_summary = BISMARK_SUMMARY.out.summary ch_versions = ch_versions.mix(BISMARK_SUMMARY.out.versions) @@ -129,11 +129,11 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { * Collect MultiQC inputs */ ch_multiqc_files = ch_bismark_summary - .mix(ch_alignment_reports.collect{ meta, align_report, dedup_report -> align_report }) - .mix(ch_alignment_reports.collect{ meta, align_report, dedup_report -> dedup_report }) - .mix(ch_methylation_report.collect{ meta, report -> report }) - .mix(ch_methylation_mbias.collect{ meta, mbias -> mbias }) - .mix(ch_bismark_report.collect{ meta, report -> report }) + .mix(ch_alignment_reports.collect{ _meta, align_report, _dedup_report -> align_report }) + .mix(ch_alignment_reports.collect{ _meta, _align_report, dedup_report -> dedup_report }) + .mix(ch_methylation_report.collect{ _meta, report -> report }) + .mix(ch_methylation_mbias.collect{ _meta, mbias -> mbias }) + .mix(ch_bismark_report.collect{ _meta, report -> report }) emit: bam = SAMTOOLS_SORT.out.bam // channel: [ val(meta), [ bam ] ] diff --git a/subworkflows/nf-core/fastq_align_dedup_bismark/meta.yml b/subworkflows/nf-core/fastq_align_dedup_bismark/meta.yml index 7622b98e892e..9c31668b6b32 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bismark/meta.yml +++ b/subworkflows/nf-core/fastq_align_dedup_bismark/meta.yml @@ -121,9 +121,9 @@ output: - multiqc: type: file description: | - Channel containing MultiQC report aggregating results across samples. - Structure: [ val(meta), path(multiqc_report.html) ] - pattern: "*.html" + Channel containing files for MultiQC input (reports, alignment reports, methylation reports). + Structure: [ path(files) ] + pattern: "*.{html,txt}" - versions: type: file description: | diff --git a/subworkflows/nf-core/fastq_align_dedup_bismark/tests/main.nf.test b/subworkflows/nf-core/fastq_align_dedup_bismark/tests/main.nf.test index 27bf692afdd7..41a18cd173f3 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bismark/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_align_dedup_bismark/tests/main.nf.test @@ -105,9 +105,11 @@ nextflow_workflow { workflow { """ input[0] = Channel.of([ - [ id:'test', single_end:true ], - file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), - file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) + [ id:'test', single_end:false ], + [ + file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), + file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) + ] ]) input[1] = Channel.of([ [:], @@ -154,9 +156,11 @@ nextflow_workflow { workflow { """ input[0] = Channel.of([ - [ id:'test', single_end:true ], - file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), - file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) + [ id:'test', single_end:false ], + [ + file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), + file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) + ] ]) input[1] = Channel.of([ [:], @@ -203,9 +207,11 @@ nextflow_workflow { workflow { """ input[0] = Channel.of([ - [ id:'test', single_end:true ], - file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), - file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) + [ id:'test', single_end:false ], + [ + file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), + file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) + ] ]) input[1] = Channel.of([ [:], @@ -302,9 +308,11 @@ nextflow_workflow { workflow { """ input[0] = Channel.of([ - [ id:'test', single_end:true ], - file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), - file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) + [ id:'test', single_end:false ], + [ + file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), + file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) + ] ]) input[1] = Channel.of([ [:], @@ -351,9 +359,11 @@ nextflow_workflow { workflow { """ input[0] = Channel.of([ - [ id:'test', single_end:true ], - file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), - file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) + [ id:'test', single_end:false ], + [ + file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), + file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) + ] ]) input[1] = Channel.of([ [:], @@ -400,9 +410,11 @@ nextflow_workflow { workflow { """ input[0] = Channel.of([ - [ id:'test', single_end:true ], - file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), - file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) + [ id:'test', single_end:false ], + [ + file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), + file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) + ] ]) input[1] = Channel.of([ [:], diff --git a/subworkflows/nf-core/fastq_align_dedup_bismark/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_align_dedup_bismark/tests/main.nf.test.snap index 7210772d9c96..3067314eeae6 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bismark/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_align_dedup_bismark/tests/main.nf.test.snap @@ -2,7 +2,7 @@ "Params: bismark_hisat paired-end | default": { "content": [ [ - "4bf31467bec7b5d5669aa4ac16f6f93f" + "37b8bb55cd310598c52a7b1376c538b8" ], [ "test.sorted.bam.bai" @@ -20,24 +20,24 @@ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.bedGraph.gz:md5,036f675959865a43f49899108d53b546" + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.bedGraph.gz:md5,bbaf7200b30dd78f578df81c65aa3b12" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, [ - "CHG_OB_Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.txt.gz:md5,d01f69d7783908ae35cfb80dba5d7177", - "CHG_OT_Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.txt.gz:md5,ce1d1bdf2179a3280f8a2127e6ea6c7f", - "CHH_OB_Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.txt.gz:md5,7d094368fc3b95cdbb45e818b7c3119f", - "CHH_OT_Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.txt.gz:md5,3b90716df9726fac04f7ab52d0ff4de4", - "CpG_OB_Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.txt.gz:md5,6d6e0d34e79e36d205699a3f91316b21", - "CpG_OT_Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.txt.gz:md5,b1ba62c4e7fb33fe4e35d203a0814552" + "CHG_OB_Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.txt.gz:md5,275586e525fa8026af3945b6fd372807", + "CHG_OT_Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.txt.gz:md5,d15db39c712f65679cce464da6152f72", + "CHH_OB_Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.txt.gz:md5,c860eff2055ebfa5ab51eaa74c844b1a", + "CHH_OT_Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.txt.gz:md5,e216e668a80eb0af621ea28bf30649a4", + "CpG_OB_Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.txt.gz:md5,ceed6d29a4364cf820ff8c5e583b207a", + "CpG_OT_Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.txt.gz:md5,9c964be8061710e61f9bda2209f725ed" ] ] ], @@ -45,39 +45,39 @@ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.bismark.cov.gz:md5,63511c46275713088957950285acd653" + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.bismark.cov.gz:md5,1b7b806b845ac9881c655ea7ab29ef2a" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated_splitting_report.txt:md5,ba02f4b97aa69b1ee1a0df5b06e34472" + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated_splitting_report.txt:md5,56456b46726a6c7123ce9b47be410f8e" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.M-bias.txt:md5,857b28589351f2c63f587a2c040db748" + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.M-bias.txt:md5,1cdd6bb3f7d6ac41a60a5312245cfb0a" ] ], [ - "Ecoli_10K_methylated_R1_bismark_hisat2_SE_report.html" + "Ecoli_10K_methylated_R1_bismark_hisat2_PE_report.html" ], - "bismark_summary_report.txt:md5,9f62c10d005c39d3e5ee7961b6b0bf6b", + "bismark_summary_report.txt:md5,70e16c0041dfbf255b70d1eb60df5c54", [ - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.M-bias.txt", - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated_splitting_report.txt", - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplication_report.txt", - "Ecoli_10K_methylated_R1_bismark_hisat2_SE_report.html", - "Ecoli_10K_methylated_R1_bismark_hisat2_SE_report.txt", + "Ecoli_10K_methylated_R1_bismark_hisat2_PE_report.html", + "Ecoli_10K_methylated_R1_bismark_hisat2_PE_report.txt", + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.M-bias.txt", + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated_splitting_report.txt", + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplication_report.txt", "bismark_summary_report.html", "bismark_summary_report.txt" ], @@ -93,12 +93,12 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-26T16:09:19.968708" + "timestamp": "2025-12-03T12:54:08.096501" }, "Params: bismark paired-end | default": { "content": [ [ - "4bf31467bec7b5d5669aa4ac16f6f93f" + "b49754b06cf7a7fc8d31b973e5ee9cc3" ], [ "test.sorted.bam.bai" @@ -116,24 +116,24 @@ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.bedGraph.gz:md5,036f675959865a43f49899108d53b546" + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.bedGraph.gz:md5,7262545b878b2c685d83566d94ab7622" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, [ - "CHG_OB_Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.txt.gz:md5,d01f69d7783908ae35cfb80dba5d7177", - "CHG_OT_Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.txt.gz:md5,ce1d1bdf2179a3280f8a2127e6ea6c7f", - "CHH_OB_Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.txt.gz:md5,7d094368fc3b95cdbb45e818b7c3119f", - "CHH_OT_Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.txt.gz:md5,3b90716df9726fac04f7ab52d0ff4de4", - "CpG_OB_Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.txt.gz:md5,6d6e0d34e79e36d205699a3f91316b21", - "CpG_OT_Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.txt.gz:md5,b1ba62c4e7fb33fe4e35d203a0814552" + "CHG_OB_Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.txt.gz:md5,a5315ec249edb9e90d04c8cd79574eb6", + "CHG_OT_Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.txt.gz:md5,d15db39c712f65679cce464da6152f72", + "CHH_OB_Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.txt.gz:md5,db9ef72b9f85ac7d0a0b70798b6b05a5", + "CHH_OT_Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.txt.gz:md5,e216e668a80eb0af621ea28bf30649a4", + "CpG_OB_Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.txt.gz:md5,eab3936aeadb93309dc853b911446969", + "CpG_OT_Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.txt.gz:md5,9c964be8061710e61f9bda2209f725ed" ] ] ], @@ -141,39 +141,39 @@ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.bismark.cov.gz:md5,63511c46275713088957950285acd653" + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.bismark.cov.gz:md5,589bf81db14b3464a7fde598ef8bb3c3" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_bt2.deduplicated_splitting_report.txt:md5,c9a24928450df13dfef288a1397342c7" + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated_splitting_report.txt:md5,7b394bfb52ef33e6c342bee0c1e545ea" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.M-bias.txt:md5,857b28589351f2c63f587a2c040db748" + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.M-bias.txt:md5,9cb860148c032fe23e520323b3aa6610" ] ], [ - "Ecoli_10K_methylated_R1_bismark_bt2_SE_report.html" + "Ecoli_10K_methylated_R1_bismark_bt2_PE_report.html" ], - "bismark_summary_report.txt:md5,855dfc95b1dbb0876aff2831380bba99", + "bismark_summary_report.txt:md5,21cfc15e5c27a6d749ce8c8bf1579476", [ - "Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.M-bias.txt", - "Ecoli_10K_methylated_R1_bismark_bt2.deduplicated_splitting_report.txt", - "Ecoli_10K_methylated_R1_bismark_bt2.deduplication_report.txt", - "Ecoli_10K_methylated_R1_bismark_bt2_SE_report.html", - "Ecoli_10K_methylated_R1_bismark_bt2_SE_report.txt", + "Ecoli_10K_methylated_R1_bismark_bt2_PE_report.html", + "Ecoli_10K_methylated_R1_bismark_bt2_PE_report.txt", + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.M-bias.txt", + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated_splitting_report.txt", + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplication_report.txt", "bismark_summary_report.html", "bismark_summary_report.txt" ], @@ -189,7 +189,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-26T16:06:07.253589" + "timestamp": "2025-12-03T12:51:46.486572" }, "Params: bismark single-end | default": { "content": [ @@ -290,7 +290,7 @@ "Params: bismark paired-end | cytosine_report": { "content": [ [ - "4bf31467bec7b5d5669aa4ac16f6f93f" + "b49754b06cf7a7fc8d31b973e5ee9cc3" ], [ "test.sorted.bam.bai" @@ -302,42 +302,42 @@ [ { "id": "test", - "single_end": true + "single_end": false }, - "test.CpG_report.txt.gz:md5,48cfcbd77d450c55fc64c8e6d939fa03" + "test.CpG_report.txt.gz:md5,42ac73af650ae9beaaa6b824421932e4" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "test.cytosine_context_summary.txt:md5,d9df9696701e5799a06a18af4e49d648" + "test.cytosine_context_summary.txt:md5,86fb169f88332e8e51606c575bf73ed6" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.bedGraph.gz:md5,036f675959865a43f49899108d53b546" + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.bedGraph.gz:md5,7262545b878b2c685d83566d94ab7622" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, [ - "CHG_OB_Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.txt.gz:md5,d01f69d7783908ae35cfb80dba5d7177", - "CHG_OT_Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.txt.gz:md5,ce1d1bdf2179a3280f8a2127e6ea6c7f", - "CHH_OB_Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.txt.gz:md5,7d094368fc3b95cdbb45e818b7c3119f", - "CHH_OT_Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.txt.gz:md5,3b90716df9726fac04f7ab52d0ff4de4", - "CpG_OB_Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.txt.gz:md5,6d6e0d34e79e36d205699a3f91316b21", - "CpG_OT_Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.txt.gz:md5,b1ba62c4e7fb33fe4e35d203a0814552" + "CHG_OB_Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.txt.gz:md5,a5315ec249edb9e90d04c8cd79574eb6", + "CHG_OT_Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.txt.gz:md5,d15db39c712f65679cce464da6152f72", + "CHH_OB_Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.txt.gz:md5,db9ef72b9f85ac7d0a0b70798b6b05a5", + "CHH_OT_Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.txt.gz:md5,e216e668a80eb0af621ea28bf30649a4", + "CpG_OB_Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.txt.gz:md5,eab3936aeadb93309dc853b911446969", + "CpG_OT_Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.txt.gz:md5,9c964be8061710e61f9bda2209f725ed" ] ] ], @@ -345,39 +345,39 @@ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.bismark.cov.gz:md5,63511c46275713088957950285acd653" + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.bismark.cov.gz:md5,589bf81db14b3464a7fde598ef8bb3c3" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_bt2.deduplicated_splitting_report.txt:md5,c9a24928450df13dfef288a1397342c7" + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated_splitting_report.txt:md5,7b394bfb52ef33e6c342bee0c1e545ea" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.M-bias.txt:md5,857b28589351f2c63f587a2c040db748" + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.M-bias.txt:md5,9cb860148c032fe23e520323b3aa6610" ] ], [ - "Ecoli_10K_methylated_R1_bismark_bt2_SE_report.html" + "Ecoli_10K_methylated_R1_bismark_bt2_PE_report.html" ], - "bismark_summary_report.txt:md5,855dfc95b1dbb0876aff2831380bba99", + "bismark_summary_report.txt:md5,21cfc15e5c27a6d749ce8c8bf1579476", [ - "Ecoli_10K_methylated_R1_bismark_bt2.deduplicated.M-bias.txt", - "Ecoli_10K_methylated_R1_bismark_bt2.deduplicated_splitting_report.txt", - "Ecoli_10K_methylated_R1_bismark_bt2.deduplication_report.txt", - "Ecoli_10K_methylated_R1_bismark_bt2_SE_report.html", - "Ecoli_10K_methylated_R1_bismark_bt2_SE_report.txt", + "Ecoli_10K_methylated_R1_bismark_bt2_PE_report.html", + "Ecoli_10K_methylated_R1_bismark_bt2_PE_report.txt", + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated.M-bias.txt", + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplicated_splitting_report.txt", + "Ecoli_10K_methylated_R1_bismark_bt2_pe.deduplication_report.txt", "bismark_summary_report.html", "bismark_summary_report.txt" ], @@ -394,12 +394,12 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-26T16:07:41.229218" + "timestamp": "2025-12-03T12:52:56.128659" }, "Params: bismark_hisat paired-end | cytosine_report": { "content": [ [ - "4bf31467bec7b5d5669aa4ac16f6f93f" + "37b8bb55cd310598c52a7b1376c538b8" ], [ "test.sorted.bam.bai" @@ -411,42 +411,42 @@ [ { "id": "test", - "single_end": true + "single_end": false }, - "test.CpG_report.txt.gz:md5,48cfcbd77d450c55fc64c8e6d939fa03" + "test.CpG_report.txt.gz:md5,fe9669f16e5102b36af1aa23ae539c45" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "test.cytosine_context_summary.txt:md5,d9df9696701e5799a06a18af4e49d648" + "test.cytosine_context_summary.txt:md5,7fe29e3f72cb9f48ccca26dbc7457971" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.bedGraph.gz:md5,036f675959865a43f49899108d53b546" + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.bedGraph.gz:md5,bbaf7200b30dd78f578df81c65aa3b12" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, [ - "CHG_OB_Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.txt.gz:md5,d01f69d7783908ae35cfb80dba5d7177", - "CHG_OT_Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.txt.gz:md5,ce1d1bdf2179a3280f8a2127e6ea6c7f", - "CHH_OB_Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.txt.gz:md5,7d094368fc3b95cdbb45e818b7c3119f", - "CHH_OT_Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.txt.gz:md5,3b90716df9726fac04f7ab52d0ff4de4", - "CpG_OB_Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.txt.gz:md5,6d6e0d34e79e36d205699a3f91316b21", - "CpG_OT_Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.txt.gz:md5,b1ba62c4e7fb33fe4e35d203a0814552" + "CHG_OB_Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.txt.gz:md5,275586e525fa8026af3945b6fd372807", + "CHG_OT_Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.txt.gz:md5,d15db39c712f65679cce464da6152f72", + "CHH_OB_Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.txt.gz:md5,c860eff2055ebfa5ab51eaa74c844b1a", + "CHH_OT_Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.txt.gz:md5,e216e668a80eb0af621ea28bf30649a4", + "CpG_OB_Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.txt.gz:md5,ceed6d29a4364cf820ff8c5e583b207a", + "CpG_OT_Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.txt.gz:md5,9c964be8061710e61f9bda2209f725ed" ] ] ], @@ -454,39 +454,39 @@ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.bismark.cov.gz:md5,63511c46275713088957950285acd653" + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.bismark.cov.gz:md5,1b7b806b845ac9881c655ea7ab29ef2a" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated_splitting_report.txt:md5,ba02f4b97aa69b1ee1a0df5b06e34472" + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated_splitting_report.txt:md5,56456b46726a6c7123ce9b47be410f8e" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.M-bias.txt:md5,857b28589351f2c63f587a2c040db748" + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.M-bias.txt:md5,1cdd6bb3f7d6ac41a60a5312245cfb0a" ] ], [ - "Ecoli_10K_methylated_R1_bismark_hisat2_SE_report.html" + "Ecoli_10K_methylated_R1_bismark_hisat2_PE_report.html" ], - "bismark_summary_report.txt:md5,9f62c10d005c39d3e5ee7961b6b0bf6b", + "bismark_summary_report.txt:md5,70e16c0041dfbf255b70d1eb60df5c54", [ - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated.M-bias.txt", - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplicated_splitting_report.txt", - "Ecoli_10K_methylated_R1_bismark_hisat2.deduplication_report.txt", - "Ecoli_10K_methylated_R1_bismark_hisat2_SE_report.html", - "Ecoli_10K_methylated_R1_bismark_hisat2_SE_report.txt", + "Ecoli_10K_methylated_R1_bismark_hisat2_PE_report.html", + "Ecoli_10K_methylated_R1_bismark_hisat2_PE_report.txt", + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated.M-bias.txt", + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplicated_splitting_report.txt", + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.deduplication_report.txt", "bismark_summary_report.html", "bismark_summary_report.txt" ], @@ -503,12 +503,12 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-26T16:10:56.996045" + "timestamp": "2025-12-03T12:55:18.043595" }, "Params: bismark_hisat paired-end | skip_deduplication": { "content": [ [ - "4bf31467bec7b5d5669aa4ac16f6f93f" + "37b8bb55cd310598c52a7b1376c538b8" ], [ "test.sorted.bam.bai" @@ -526,24 +526,24 @@ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_hisat2.bedGraph.gz:md5,036f675959865a43f49899108d53b546" + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.bedGraph.gz:md5,bbaf7200b30dd78f578df81c65aa3b12" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, [ - "CHG_OB_Ecoli_10K_methylated_R1_bismark_hisat2.txt.gz:md5,d01f69d7783908ae35cfb80dba5d7177", - "CHG_OT_Ecoli_10K_methylated_R1_bismark_hisat2.txt.gz:md5,ce1d1bdf2179a3280f8a2127e6ea6c7f", - "CHH_OB_Ecoli_10K_methylated_R1_bismark_hisat2.txt.gz:md5,7d094368fc3b95cdbb45e818b7c3119f", - "CHH_OT_Ecoli_10K_methylated_R1_bismark_hisat2.txt.gz:md5,3b90716df9726fac04f7ab52d0ff4de4", - "CpG_OB_Ecoli_10K_methylated_R1_bismark_hisat2.txt.gz:md5,6d6e0d34e79e36d205699a3f91316b21", - "CpG_OT_Ecoli_10K_methylated_R1_bismark_hisat2.txt.gz:md5,b1ba62c4e7fb33fe4e35d203a0814552" + "CHG_OB_Ecoli_10K_methylated_R1_bismark_hisat2_pe.txt.gz:md5,275586e525fa8026af3945b6fd372807", + "CHG_OT_Ecoli_10K_methylated_R1_bismark_hisat2_pe.txt.gz:md5,d15db39c712f65679cce464da6152f72", + "CHH_OB_Ecoli_10K_methylated_R1_bismark_hisat2_pe.txt.gz:md5,c860eff2055ebfa5ab51eaa74c844b1a", + "CHH_OT_Ecoli_10K_methylated_R1_bismark_hisat2_pe.txt.gz:md5,e216e668a80eb0af621ea28bf30649a4", + "CpG_OB_Ecoli_10K_methylated_R1_bismark_hisat2_pe.txt.gz:md5,ceed6d29a4364cf820ff8c5e583b207a", + "CpG_OT_Ecoli_10K_methylated_R1_bismark_hisat2_pe.txt.gz:md5,9c964be8061710e61f9bda2209f725ed" ] ] ], @@ -551,38 +551,38 @@ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_hisat2.bismark.cov.gz:md5,63511c46275713088957950285acd653" + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.bismark.cov.gz:md5,1b7b806b845ac9881c655ea7ab29ef2a" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_hisat2_splitting_report.txt:md5,c31404f4bfc6066ae9ab182a144bc0ee" + "Ecoli_10K_methylated_R1_bismark_hisat2_pe_splitting_report.txt:md5,0b10b254a734cb9e6d995f551c43f3b8" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_hisat2.M-bias.txt:md5,857b28589351f2c63f587a2c040db748" + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.M-bias.txt:md5,1cdd6bb3f7d6ac41a60a5312245cfb0a" ] ], [ - "Ecoli_10K_methylated_R1_bismark_hisat2_SE_report.html" + "Ecoli_10K_methylated_R1_bismark_hisat2_PE_report.html" ], - "bismark_summary_report.txt:md5,dd73bb37e3116c25480990bd37f3f99f", + "bismark_summary_report.txt:md5,71a32316dad67c92c874c9e95d6abcaf", [ - "Ecoli_10K_methylated_R1_bismark_hisat2.M-bias.txt", - "Ecoli_10K_methylated_R1_bismark_hisat2_SE_report.html", - "Ecoli_10K_methylated_R1_bismark_hisat2_SE_report.txt", - "Ecoli_10K_methylated_R1_bismark_hisat2_splitting_report.txt", + "Ecoli_10K_methylated_R1_bismark_hisat2_PE_report.html", + "Ecoli_10K_methylated_R1_bismark_hisat2_PE_report.txt", + "Ecoli_10K_methylated_R1_bismark_hisat2_pe.M-bias.txt", + "Ecoli_10K_methylated_R1_bismark_hisat2_pe_splitting_report.txt", "bismark_summary_report.html", "bismark_summary_report.txt" ], @@ -597,12 +597,12 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-26T16:03:49.322364" + "timestamp": "2025-12-03T12:54:41.001127" }, "Params: bismark paired-end | skip_deduplication": { "content": [ [ - "4bf31467bec7b5d5669aa4ac16f6f93f" + "b49754b06cf7a7fc8d31b973e5ee9cc3" ], [ "test.sorted.bam.bai" @@ -620,24 +620,24 @@ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_bt2.bedGraph.gz:md5,036f675959865a43f49899108d53b546" + "Ecoli_10K_methylated_R1_bismark_bt2_pe.bedGraph.gz:md5,7262545b878b2c685d83566d94ab7622" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, [ - "CHG_OB_Ecoli_10K_methylated_R1_bismark_bt2.txt.gz:md5,d01f69d7783908ae35cfb80dba5d7177", - "CHG_OT_Ecoli_10K_methylated_R1_bismark_bt2.txt.gz:md5,ce1d1bdf2179a3280f8a2127e6ea6c7f", - "CHH_OB_Ecoli_10K_methylated_R1_bismark_bt2.txt.gz:md5,7d094368fc3b95cdbb45e818b7c3119f", - "CHH_OT_Ecoli_10K_methylated_R1_bismark_bt2.txt.gz:md5,3b90716df9726fac04f7ab52d0ff4de4", - "CpG_OB_Ecoli_10K_methylated_R1_bismark_bt2.txt.gz:md5,6d6e0d34e79e36d205699a3f91316b21", - "CpG_OT_Ecoli_10K_methylated_R1_bismark_bt2.txt.gz:md5,b1ba62c4e7fb33fe4e35d203a0814552" + "CHG_OB_Ecoli_10K_methylated_R1_bismark_bt2_pe.txt.gz:md5,a5315ec249edb9e90d04c8cd79574eb6", + "CHG_OT_Ecoli_10K_methylated_R1_bismark_bt2_pe.txt.gz:md5,d15db39c712f65679cce464da6152f72", + "CHH_OB_Ecoli_10K_methylated_R1_bismark_bt2_pe.txt.gz:md5,db9ef72b9f85ac7d0a0b70798b6b05a5", + "CHH_OT_Ecoli_10K_methylated_R1_bismark_bt2_pe.txt.gz:md5,e216e668a80eb0af621ea28bf30649a4", + "CpG_OB_Ecoli_10K_methylated_R1_bismark_bt2_pe.txt.gz:md5,eab3936aeadb93309dc853b911446969", + "CpG_OT_Ecoli_10K_methylated_R1_bismark_bt2_pe.txt.gz:md5,9c964be8061710e61f9bda2209f725ed" ] ] ], @@ -645,38 +645,38 @@ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_bt2.bismark.cov.gz:md5,63511c46275713088957950285acd653" + "Ecoli_10K_methylated_R1_bismark_bt2_pe.bismark.cov.gz:md5,589bf81db14b3464a7fde598ef8bb3c3" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_bt2_splitting_report.txt:md5,7e8d03d9dce62c62a9fe1703e22022e9" + "Ecoli_10K_methylated_R1_bismark_bt2_pe_splitting_report.txt:md5,d827deca8065fce65c814bf09a15ba92" ] ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "Ecoli_10K_methylated_R1_bismark_bt2.M-bias.txt:md5,857b28589351f2c63f587a2c040db748" + "Ecoli_10K_methylated_R1_bismark_bt2_pe.M-bias.txt:md5,9cb860148c032fe23e520323b3aa6610" ] ], [ - "Ecoli_10K_methylated_R1_bismark_bt2_SE_report.html" + "Ecoli_10K_methylated_R1_bismark_bt2_PE_report.html" ], - "bismark_summary_report.txt:md5,9f639cca6fe43c0461d2da88d931a036", + "bismark_summary_report.txt:md5,87d0db5195a75381dec2f2809daa0b45", [ - "Ecoli_10K_methylated_R1_bismark_bt2.M-bias.txt", - "Ecoli_10K_methylated_R1_bismark_bt2_SE_report.html", - "Ecoli_10K_methylated_R1_bismark_bt2_SE_report.txt", - "Ecoli_10K_methylated_R1_bismark_bt2_splitting_report.txt", + "Ecoli_10K_methylated_R1_bismark_bt2_PE_report.html", + "Ecoli_10K_methylated_R1_bismark_bt2_PE_report.txt", + "Ecoli_10K_methylated_R1_bismark_bt2_pe.M-bias.txt", + "Ecoli_10K_methylated_R1_bismark_bt2_pe_splitting_report.txt", "bismark_summary_report.html", "bismark_summary_report.txt" ], @@ -691,7 +691,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-26T16:06:51.373216" + "timestamp": "2025-12-03T12:52:19.185514" }, "Params: bismark_hisat single-end | default": { "content": [ diff --git a/subworkflows/nf-core/fastq_align_dedup_bwamem/main.nf b/subworkflows/nf-core/fastq_align_dedup_bwamem/main.nf index ef736c841057..026bbf6f7a6a 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwamem/main.nf +++ b/subworkflows/nf-core/fastq_align_dedup_bwamem/main.nf @@ -1,7 +1,7 @@ -include { FASTQ_ALIGN_BWA } from '../fastq_align_bwa/main' -include { PICARD_ADDORREPLACEREADGROUPS } from '../../../modules/nf-core/picard/addorreplacereadgroups/main' -include { PICARD_MARKDUPLICATES } from '../../../modules/nf-core/picard/markduplicates/main' -include { SAMTOOLS_INDEX } from '../../../modules/nf-core/samtools/index/main' +include { FASTQ_ALIGN_BWA } from '../fastq_align_bwa/main' +include { PICARD_ADDORREPLACEREADGROUPS } from '../../../modules/nf-core/picard/addorreplacereadgroups/main' +include { PICARD_MARKDUPLICATES } from '../../../modules/nf-core/picard/markduplicates/main' +include { SAMTOOLS_INDEX } from '../../../modules/nf-core/samtools/index/main' workflow FASTQ_ALIGN_DEDUP_BWAMEM { @@ -9,19 +9,18 @@ workflow FASTQ_ALIGN_DEDUP_BWAMEM { ch_reads // channel: [ val(meta), [ reads ] ] ch_fasta // channel: [ val(meta), [ fasta ] ] ch_fasta_index // channel: [ val(meta), [ fasta index ] ] - ch_bwamem_index // channel: [ val(meta), [ bwam index ] ] + ch_bwamem_index // channel: [ val(meta), [ bwamem index ] ] skip_deduplication // boolean: whether to deduplicate alignments - use_gpu // boolean: whether to use GPU or CPU for bwamem alignment main: - - ch_alignment = Channel.empty() - ch_alignment_index = Channel.empty() - ch_flagstat = Channel.empty() - ch_stats = Channel.empty() - ch_picard_metrics = Channel.empty() - ch_multiqc_files = Channel.empty() - ch_versions = Channel.empty() + ch_alignment = channel.empty() + ch_alignment_index = channel.empty() + ch_flagstat = channel.empty() + ch_stats = channel.empty() + ch_idxstats = channel.empty() + ch_picard_metrics = channel.empty() + ch_multiqc_files = channel.empty() + ch_versions = channel.empty() FASTQ_ALIGN_BWA ( ch_reads, @@ -29,11 +28,11 @@ workflow FASTQ_ALIGN_DEDUP_BWAMEM { true, // val_sort_bam hardcoded to true ch_fasta ) - ch_alignment = ch_alignment.mix(FASTQ_ALIGN_BWA.out.bam) - ch_alignment_index = ch_alignment.mix(FASTQ_ALIGN_BWA.out.bai) - ch_stats = ch_alignment.mix(FASTQ_ALIGN_BWA.out.stats) // channel: [ val(meta), path(stats) ] - ch_flagstat = ch_alignment.mix(FASTQ_ALIGN_BWA.out.flagstat) // channel: [ val(meta), path(flagstat) ] - ch_idxstats = ch_alignment.mix(FASTQ_ALIGN_BWA.out.idxstats) // channel: [ val(meta), path(idxstats) ] + ch_alignment = FASTQ_ALIGN_BWA.out.bam // channel: [ val(meta), [ bam ] ] + ch_alignment_index = FASTQ_ALIGN_BWA.out.bai // channel: [ val(meta), [ bai ] ] + ch_stats = FASTQ_ALIGN_BWA.out.stats // channel: [ val(meta), path(stats) ] + ch_flagstat = FASTQ_ALIGN_BWA.out.flagstat // channel: [ val(meta), path(flagstat) ] + ch_idxstats = FASTQ_ALIGN_BWA.out.idxstats // channel: [ val(meta), path(idxstats) ] ch_versions = ch_versions.mix(FASTQ_ALIGN_BWA.out.versions.first()) if (!skip_deduplication) { @@ -48,9 +47,8 @@ workflow FASTQ_ALIGN_DEDUP_BWAMEM { ch_versions = ch_versions.mix(PICARD_ADDORREPLACEREADGROUPS.out.versions.first()) /* - * Run Picard MarkDuplicates with the --REMOVE_DUPLICATES true flag + * Run Picard MarkDuplicates to mark duplicates */ - PICARD_MARKDUPLICATES ( PICARD_ADDORREPLACEREADGROUPS.out.bam, ch_fasta, @@ -73,18 +71,18 @@ workflow FASTQ_ALIGN_DEDUP_BWAMEM { /* * Collect MultiQC inputs */ - ch_multiqc_files = ch_picard_metrics.collect{ meta, metrics -> metrics } - .mix(ch_flagstat.collect{ meta, flagstat -> flagstat }) - .mix(ch_stats.collect{ meta, stats -> stats }) - .mix(ch_idxstats.collect{ meta, stats -> stats }) + ch_multiqc_files = ch_picard_metrics.collect{ _meta, metrics -> metrics } + .mix(ch_flagstat.collect{ _meta, flagstat -> flagstat }) + .mix(ch_stats.collect{ _meta, stats -> stats }) + .mix(ch_idxstats.collect{ _meta, stats -> stats }) emit: - bam = ch_alignment // channel: [ val(meta), [ bam ] ] - bai = ch_alignment_index // channel: [ val(meta), [ bai ] ] - samtools_flagstat = ch_flagstat // channel: [ val(meta), [ flagstat ] ] - samtools_stats = ch_stats // channel: [ val(meta), [ stats ] ] - samtools_index_stats = ch_idxstats // channel: [ val(meta), [ idxstats ] ] - picard_metrics = ch_picard_metrics // channel: [ val(meta), [ metrics ] ] - multiqc = ch_multiqc_files // channel: [ *{html,txt} ] - versions = ch_versions // channel: [ versions.yml ] + bam = ch_alignment // channel: [ val(meta), [ bam ] ] + bai = ch_alignment_index // channel: [ val(meta), [ bai ] ] + samtools_flagstat = ch_flagstat // channel: [ val(meta), [ flagstat ] ] + samtools_stats = ch_stats // channel: [ val(meta), [ stats ] ] + samtools_idxstats = ch_idxstats // channel: [ val(meta), [ idxstats ] ] + picard_metrics = ch_picard_metrics // channel: [ val(meta), [ metrics ] ] + multiqc = ch_multiqc_files // channel: [ *{html,txt} ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/fastq_align_dedup_bwamem/meta.yml b/subworkflows/nf-core/fastq_align_dedup_bwamem/meta.yml index a518a058aa38..fd6670e2af03 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwamem/meta.yml +++ b/subworkflows/nf-core/fastq_align_dedup_bwamem/meta.yml @@ -81,9 +81,9 @@ output: - multiqc: type: file description: | - Channel containing MultiQC report aggregating results across samples. - Structure: [ val(meta), path(multiqc_report.html) ] - pattern: "*.html" + Channel containing files for MultiQC input (metrics, stats, flagstat, idxstats). + Structure: [ path(file) ] + pattern: "*{.txt,.stats,.flagstat,.idxstats}" - versions: type: file description: | diff --git a/subworkflows/nf-core/fastq_align_dedup_bwamem/tests/main.nf.test b/subworkflows/nf-core/fastq_align_dedup_bwamem/tests/main.nf.test index 5b5354f7dc89..56c996c5c586 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwamem/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_align_dedup_bwamem/tests/main.nf.test @@ -57,7 +57,6 @@ nextflow_workflow { ]) input[3] = BWA_INDEX.out.index input[4] = false // skip_deduplication - input[5] = false // use_gpu """ } } @@ -70,7 +69,7 @@ nextflow_workflow { workflow.out.bai.collect { meta, bai -> file(bai).name }, workflow.out.samtools_flagstat, workflow.out.samtools_stats, - workflow.out.samtools_index_stats, + workflow.out.samtools_idxstats, workflow.out.picard_metrics.collect { meta, metrics -> file(metrics).name }, workflow.out.multiqc.flatten().collect { path -> file(path).name }, workflow.out.versions @@ -86,7 +85,7 @@ nextflow_workflow { workflow { """ input[0] = Channel.of([ - [ id:'test', single_end:true ], + [ id:'test', single_end:false ], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ]) @@ -100,7 +99,6 @@ nextflow_workflow { ]) input[3] = BWA_INDEX.out.index input[4] = false // skip_deduplication - input[5] = false // use_gpu """ } } @@ -113,7 +111,7 @@ nextflow_workflow { workflow.out.bai.collect { meta, bai -> file(bai).name }, workflow.out.samtools_flagstat, workflow.out.samtools_stats, - workflow.out.samtools_index_stats, + workflow.out.samtools_idxstats, workflow.out.picard_metrics.collect { meta, metrics -> file(metrics).name }, workflow.out.multiqc.flatten().collect { path -> file(path).name }, workflow.out.versions @@ -129,7 +127,7 @@ nextflow_workflow { workflow { """ input[0] = Channel.of([ - [ id:'test', single_end:true ], + [ id:'test', single_end:false ], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ]) @@ -143,7 +141,6 @@ nextflow_workflow { ]) input[3] = BWA_INDEX.out.index input[4] = true // skip_deduplication - input[5] = false // use_gpu """ } } @@ -156,7 +153,7 @@ nextflow_workflow { workflow.out.bai.collect { meta, bai -> file(bai).name }, workflow.out.samtools_flagstat, workflow.out.samtools_stats, - workflow.out.samtools_index_stats, + workflow.out.samtools_idxstats, workflow.out.picard_metrics.collect { meta, metrics -> file(metrics).name }, workflow.out.multiqc.flatten().collect { path -> file(path).name }, workflow.out.versions @@ -185,7 +182,6 @@ nextflow_workflow { ]) input[3] = BWA_INDEX.out.index input[4] = false // skip_deduplication - input[5] = false // use_gpu """ } } diff --git a/subworkflows/nf-core/fastq_align_dedup_bwamem/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_align_dedup_bwamem/tests/main.nf.test.snap index 214e37f4d4d3..5ee3a0738c38 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwamem/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_align_dedup_bwamem/tests/main.nf.test.snap @@ -14,23 +14,9 @@ "single_end": true }, "test.flagstat:md5,2191911d72575a2358b08b1df64ccb53" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,969d4fb42ba23bba181aecc1ae89ab4b" ] ], [ - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,969d4fb42ba23bba181aecc1ae89ab4b" - ], [ { "id": "test", @@ -46,13 +32,6 @@ "single_end": true }, "test.idxstats:md5,613e048487662c694aa4a2f73ca96a20" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,969d4fb42ba23bba181aecc1ae89ab4b" ] ], [ @@ -60,11 +39,8 @@ ], [ "test.deduped.sorted.MarkDuplicates.metrics.txt", - "test.sorted.bam", "test.flagstat", - "test.sorted.bam", "test.idxstats", - "test.sorted.bam", "test.stats" ], [ @@ -75,10 +51,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-10-24T15:06:49.6951852" + "timestamp": "2025-12-03T12:27:38.204299" }, "Params: bwamem paired-end - skip_deduplication": { "content": [ @@ -86,37 +62,22 @@ "94fcf617f5b994584c4e8d4044e16b4f" ], [ - "test.sorted.bam", "test.sorted.bam.bai" ], [ [ { "id": "test", - "single_end": true + "single_end": false }, "test.flagstat:md5,2191911d72575a2358b08b1df64ccb53" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,969d4fb42ba23bba181aecc1ae89ab4b" ] ], [ [ { "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,969d4fb42ba23bba181aecc1ae89ab4b" - ], - [ - { - "id": "test", - "single_end": true + "single_end": false }, "test.stats:md5,0883b19c92a783883b3e11d5bfcc5d6a" ] @@ -125,27 +86,17 @@ [ { "id": "test", - "single_end": true + "single_end": false }, "test.idxstats:md5,613e048487662c694aa4a2f73ca96a20" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,969d4fb42ba23bba181aecc1ae89ab4b" ] ], [ ], [ - "test.sorted.bam", "test.flagstat", - "test.sorted.bam", "test.idxstats", - "test.sorted.bam", "test.stats" ], [ @@ -153,10 +104,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-10-24T15:07:14.224268922" + "timestamp": "2025-12-03T12:28:09.085652" }, "Params: bwamem single-end - default - stub": { "content": [ @@ -186,23 +137,9 @@ "single_end": true }, "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "3": [ - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" - ], [ { "id": "test", @@ -218,13 +155,6 @@ "single_end": true }, "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "5": [ @@ -241,15 +171,12 @@ "test.deduped.sorted.MarkDuplicates.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ], [ - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e", "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" ], [ - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e", "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ], [ - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e", "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], @@ -282,15 +209,12 @@ "test.deduped.sorted.MarkDuplicates.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ], [ - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e", "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" ], [ - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e", "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ], [ - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e", "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], @@ -310,39 +234,18 @@ "single_end": true }, "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "samtools_index_stats": [ + "samtools_idxstats": [ [ { "id": "test", "single_end": true }, "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "samtools_stats": [ - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" - ], [ { "id": "test", @@ -383,10 +286,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-10-24T15:07:27.497220186" + "timestamp": "2025-12-03T12:28:25.358403" }, "Params: bwamem paired-end - default": { "content": [ @@ -400,30 +303,16 @@ [ { "id": "test", - "single_end": true + "single_end": false }, "test.flagstat:md5,2191911d72575a2358b08b1df64ccb53" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,969d4fb42ba23bba181aecc1ae89ab4b" ] ], [ [ { "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,969d4fb42ba23bba181aecc1ae89ab4b" - ], - [ - { - "id": "test", - "single_end": true + "single_end": false }, "test.stats:md5,0883b19c92a783883b3e11d5bfcc5d6a" ] @@ -432,16 +321,9 @@ [ { "id": "test", - "single_end": true + "single_end": false }, "test.idxstats:md5,613e048487662c694aa4a2f73ca96a20" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,969d4fb42ba23bba181aecc1ae89ab4b" ] ], [ @@ -449,11 +331,8 @@ ], [ "test.deduped.sorted.MarkDuplicates.metrics.txt", - "test.sorted.bam", "test.flagstat", - "test.sorted.bam", "test.idxstats", - "test.sorted.bam", "test.stats" ], [ @@ -464,9 +343,9 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-10-24T15:07:05.175157122" + "timestamp": "2025-12-03T12:27:56.314782" } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf b/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf index 1e9c916bcdcc..2ea49653372c 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf +++ b/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf @@ -18,14 +18,13 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { use_gpu // boolean: whether to use GPU or CPU for bwameth alignment main: - - ch_alignment = Channel.empty() - ch_alignment_index = Channel.empty() - ch_samtools_flagstat = Channel.empty() - ch_samtools_stats = Channel.empty() - ch_picard_metrics = Channel.empty() - ch_multiqc_files = Channel.empty() - ch_versions = Channel.empty() + ch_alignment = channel.empty() + ch_alignment_index = channel.empty() + ch_samtools_flagstat = channel.empty() + ch_samtools_stats = channel.empty() + ch_picard_metrics = channel.empty() + ch_multiqc_files = channel.empty() + ch_versions = channel.empty() /* * Align with bwameth @@ -117,17 +116,17 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { /* * Collect MultiQC inputs */ - ch_multiqc_files = ch_picard_metrics.collect{ meta, metrics -> metrics } - .mix(ch_samtools_flagstat.collect{ meta, flagstat -> flagstat }) - .mix(ch_samtools_stats.collect{ meta, stats -> stats }) + ch_multiqc_files = ch_picard_metrics.collect{ _meta, metrics -> metrics } + .mix(ch_samtools_flagstat.collect{ _meta, flagstat -> flagstat }) + .mix(ch_samtools_stats.collect{ _meta, stats -> stats }) emit: - bam = ch_alignment // channel: [ val(meta), [ bam ] ] - bai = ch_alignment_index // channel: [ val(meta), [ bai ] ] - samtools_flagstat = ch_samtools_flagstat // channel: [ val(meta), [ flagstat ] ] - samtools_stats = ch_samtools_stats // channel: [ val(meta), [ stats ] ] - picard_metrics = ch_picard_metrics // channel: [ val(meta), [ metrics ] ] - multiqc = ch_multiqc_files // channel: [ *{html,txt} ] - versions = ch_versions // channel: [ versions.yml ] + bam = ch_alignment // channel: [ val(meta), [ bam ] ] + bai = ch_alignment_index // channel: [ val(meta), [ bai ] ] + samtools_flagstat = ch_samtools_flagstat // channel: [ val(meta), [ flagstat ] ] + samtools_stats = ch_samtools_stats // channel: [ val(meta), [ stats ] ] + picard_metrics = ch_picard_metrics // channel: [ val(meta), [ metrics ] ] + multiqc = ch_multiqc_files // channel: [ *{html,txt} ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/fastq_align_dedup_bwameth/meta.yml b/subworkflows/nf-core/fastq_align_dedup_bwameth/meta.yml index c85f88d3521c..338332e5a5d8 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwameth/meta.yml +++ b/subworkflows/nf-core/fastq_align_dedup_bwameth/meta.yml @@ -84,9 +84,9 @@ output: - multiqc: type: file description: | - Channel containing MultiQC report aggregating results across samples. - Structure: [ val(meta), path(multiqc_report.html) ] - pattern: "*.html" + Channel containing files for MultiQC input (metrics, stats, flagstat). + Structure: [ path(files) ] + pattern: "*.{txt,stats,flagstat}" - versions: type: file description: | diff --git a/subworkflows/nf-core/fastq_align_dedup_bwameth/tests/main.nf.test b/subworkflows/nf-core/fastq_align_dedup_bwameth/tests/main.nf.test index 321d900f5461..e64c44740e48 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwameth/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_align_dedup_bwameth/tests/main.nf.test @@ -80,7 +80,7 @@ nextflow_workflow { workflow { """ input[0] = Channel.of([ - [ id:'test', single_end:true ], + [ id:'test', single_end:false ], file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) ]) @@ -122,7 +122,7 @@ nextflow_workflow { workflow { """ input[0] = Channel.of([ - [ id:'test', single_end:true ], + [ id:'test', single_end:false ], file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R1.fastq.gz', checkIfExists: true), file('https://github.com/nf-core/test-datasets/raw/methylseq/testdata/Ecoli_10K_methylated_R2.fastq.gz', checkIfExists: true) ]) diff --git a/subworkflows/nf-core/fastq_align_dedup_bwameth/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_align_dedup_bwameth/tests/main.nf.test.snap index 61d72a8439fa..885df4ab2064 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwameth/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_align_dedup_bwameth/tests/main.nf.test.snap @@ -59,7 +59,7 @@ [ { "id": "test", - "single_end": true + "single_end": false }, "test.flagstat:md5,4ff87d121ca174953734723938c99081" ] @@ -68,7 +68,7 @@ [ { "id": "test", - "single_end": true + "single_end": false }, "test.stats:md5,8052e9c021ba6ebf5b7aed5538f7008f" ] @@ -90,7 +90,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-01T03:10:41.87614" + "timestamp": "2025-12-03T12:40:33.660146" }, "Params: bwameth paired-end | default": { "content": [ @@ -104,7 +104,7 @@ [ { "id": "test", - "single_end": true + "single_end": false }, "test.flagstat:md5,4ff87d121ca174953734723938c99081" ] @@ -113,7 +113,7 @@ [ { "id": "test", - "single_end": true + "single_end": false }, "test.stats:md5,8052e9c021ba6ebf5b7aed5538f7008f" ] @@ -138,6 +138,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-01T03:10:25.929797" + "timestamp": "2025-12-03T12:40:19.798072" } } \ No newline at end of file From 19b67c459c35cc43e0b532be901388a4dec925f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Thu, 4 Dec 2025 16:01:58 +0100 Subject: [PATCH 14/83] Update test files for Glimpse (#9467) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update glimpse * Update chunk * Update concordance * Revert changes * Fix glimpse test * Fix glimpse * Fix glimpse2 tests * Update sbwf * Remove old snapshots * Update glimpse * Update modules/nf-core/glimpse2/concordance/tests/main.nf.test Co-authored-by: Matthias Hörtenhuber * Update test --------- Co-authored-by: LouisLeNezet Co-authored-by: Matthias Hörtenhuber --- modules/nf-core/glimpse/chunk/main.nf | 1 + .../nf-core/glimpse/chunk/tests/main.nf.test | 15 +- .../glimpse/chunk/tests/main.nf.test.snap | 12 +- .../glimpse/chunk/tests/nextflow.config | 5 +- modules/nf-core/glimpse/concordance/main.nf | 6 +- .../glimpse/concordance/tests/main.nf.test | 76 ++---- .../concordance/tests/main.nf.test.snap | 119 +++++++-- .../glimpse/concordance/tests/nextflow.config | 5 + modules/nf-core/glimpse/ligate/main.nf | 6 +- .../nf-core/glimpse/ligate/tests/main.nf.test | 49 ++-- .../glimpse/ligate/tests/main.nf.test.snap | 30 ++- modules/nf-core/glimpse/phase/main.nf | 1 + .../nf-core/glimpse/phase/tests/main.nf.test | 51 ++-- .../glimpse/phase/tests/main.nf.test.snap | 36 ++- modules/nf-core/glimpse/sample/main.nf | 3 +- modules/nf-core/glimpse/sample/meta.yml | 7 +- .../nf-core/glimpse/sample/tests/main.nf.test | 51 ++-- .../glimpse/sample/tests/main.nf.test.snap | 25 +- .../nf-core/glimpse2/chunk/tests/main.nf.test | 2 +- .../glimpse2/chunk/tests/main.nf.test.snap | 8 +- modules/nf-core/glimpse2/concordance/main.nf | 2 +- .../glimpse2/concordance/tests/main.nf.test | 43 +-- .../concordance/tests/main.nf.test.snap | 249 ++++++++++++++---- .../glimpse2/ligate/tests/main.nf.test | 41 +-- .../glimpse2/ligate/tests/main.nf.test.snap | 28 +- .../nf-core/glimpse2/phase/tests/main.nf.test | 163 +++++++----- .../glimpse2/phase/tests/main.nf.test.snap | 108 +++++--- .../glimpse2/phase/tests/nextflow.config | 1 + .../splitreference/tests/main.nf.test | 2 +- .../nf-core/multiple_impute_glimpse2/main.nf | 14 +- .../tests/main.nf.test | 16 +- .../tests/main.nf.test.snap | 16 +- .../nf-core/vcf_impute_glimpse/main.nf | 16 +- .../vcf_impute_glimpse/tests/main.nf.test | 36 +-- .../tests/main.nf.test.snap | 100 +++---- 35 files changed, 834 insertions(+), 509 deletions(-) create mode 100644 modules/nf-core/glimpse/concordance/tests/nextflow.config diff --git a/modules/nf-core/glimpse/chunk/main.nf b/modules/nf-core/glimpse/chunk/main.nf index 9ea9ef043c47..c8d92f472997 100644 --- a/modules/nf-core/glimpse/chunk/main.nf +++ b/modules/nf-core/glimpse/chunk/main.nf @@ -37,6 +37,7 @@ process GLIMPSE_CHUNK { stub: def prefix = task.ext.prefix ?: "${meta.id}" + """ touch ${prefix}.txt diff --git a/modules/nf-core/glimpse/chunk/tests/main.nf.test b/modules/nf-core/glimpse/chunk/tests/main.nf.test index 4c278af1e60b..746feae002da 100644 --- a/modules/nf-core/glimpse/chunk/tests/main.nf.test +++ b/modules/nf-core/glimpse/chunk/tests/main.nf.test @@ -3,22 +3,25 @@ nextflow_process { name "Test Process GLIMPSE_CHUNK" script "../main.nf" process "GLIMPSE_CHUNK" + config "./nextflow.config" + tag "glimpse" tag "glimpse/chunk" tag "modules_nfcore" tag "modules" - test("Should run without failures") { - config "modules/nf-core/glimpse/chunk/tests/nextflow.config" - + test("homo_sapiens - vcf chr 22") { when { + params{ + glimpse_args = "--window-size 2000000 --buffer-size 200000" + } process { """ input[0] = [ [ id:'input' ], // meta map - file(params.test_data['homo_sapiens']['genome']['mills_and_1000g_indels_21_vcf_gz'], checkIfExists: true), - file(params.test_data['homo_sapiens']['genome']['mills_and_1000g_indels_21_vcf_gz_tbi'], checkIfExists: true), - "chr21" + 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" ] """ } diff --git a/modules/nf-core/glimpse/chunk/tests/main.nf.test.snap b/modules/nf-core/glimpse/chunk/tests/main.nf.test.snap index 0490a8e4de7f..bd580988fbec 100644 --- a/modules/nf-core/glimpse/chunk/tests/main.nf.test.snap +++ b/modules/nf-core/glimpse/chunk/tests/main.nf.test.snap @@ -1,5 +1,5 @@ { - "Should run without failures": { + "homo_sapiens - vcf chr 22": { "content": [ { "0": [ @@ -7,7 +7,7 @@ { "id": "input" }, - "input.txt:md5,9e5562b3f94857b8189b59849ce65cfb" + "input.txt:md5,38bc015bc7bb9f4fc0fdb08a698cfc78" ] ], "1": [ @@ -18,7 +18,7 @@ { "id": "input" }, - "input.txt:md5,9e5562b3f94857b8189b59849ce65cfb" + "input.txt:md5,38bc015bc7bb9f4fc0fdb08a698cfc78" ] ], "versions": [ @@ -26,6 +26,10 @@ ] } ], - "timestamp": "2023-10-16T15:55:52.457257547" + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-26T19:06:32.115560314" } } \ No newline at end of file diff --git a/modules/nf-core/glimpse/chunk/tests/nextflow.config b/modules/nf-core/glimpse/chunk/tests/nextflow.config index 8302ea19436e..8f4c838e95c4 100644 --- a/modules/nf-core/glimpse/chunk/tests/nextflow.config +++ b/modules/nf-core/glimpse/chunk/tests/nextflow.config @@ -1,9 +1,6 @@ process { withName: GLIMPSE_CHUNK { - ext.args = [ - "--window-size 2000000", - "--buffer-size 200000" - ].join(' ') + ext.args = { "${params.glimpse_args}" } ext.prefix = { "${meta.id}" } } } diff --git a/modules/nf-core/glimpse/concordance/main.nf b/modules/nf-core/glimpse/concordance/main.nf index 82e784745235..4a70a6afffed 100644 --- a/modules/nf-core/glimpse/concordance/main.nf +++ b/modules/nf-core/glimpse/concordance/main.nf @@ -20,7 +20,6 @@ process GLIMPSE_CONCORDANCE { tuple val(meta), path("*.rsquare.grp.txt.gz"), emit: rsquare_grp tuple val(meta), path("*.rsquare.spl.txt.gz"), emit: rsquare_spl path "versions.yml" , emit: versions - when: task.ext.when == null || task.ext.when @@ -42,13 +41,14 @@ process GLIMPSE_CONCORDANCE { $bins_cmd cat <<-END_VERSIONS > versions.yml - "${task.process}": - glimpse: "\$(GLIMPSE_concordance --help | sed -nr '/Version/p' | grep -o -E '([0-9]+.){1,2}[0-9]')" + "${task.process}": + glimpse: "\$(GLIMPSE_concordance --help | sed -nr '/Version/p' | grep -o -E '([0-9]+.){1,2}[0-9]')" END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" + """ echo "" | gzip > ${prefix}.error.cal.txt.gz echo "" | gzip > ${prefix}.error.grp.txt.gz diff --git a/modules/nf-core/glimpse/concordance/tests/main.nf.test b/modules/nf-core/glimpse/concordance/tests/main.nf.test index ef6d36b8aff8..1a3bb2f80118 100644 --- a/modules/nf-core/glimpse/concordance/tests/main.nf.test +++ b/modules/nf-core/glimpse/concordance/tests/main.nf.test @@ -4,6 +4,8 @@ nextflow_process { script "../main.nf" process "GLIMPSE_CONCORDANCE" + config "./nextflow.config" + tag "modules" tag "modules_nfcore" tag "glimpse" @@ -12,64 +14,21 @@ nextflow_process { tag "bcftools/index" test("test_glimpse_concordance") { - setup { - run("GLIMPSE_PHASE") { - script "../../phase/main.nf" - process { - """ - ch_sample = Channel.of('NA12878 2').collectFile(name: 'sampleinfos.txt') - region = Channel.fromList([ - ["chr21:16600000-16750000","chr21:16650000-16700000"] - ]) - input_vcf = Channel.of([ - [ id:'input'], // meta map - file(params.modules_testdata_base_path + "delete_me/glimpse/NA12878.chr21.s.1x.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "delete_me/glimpse/NA12878.chr21.s.1x.vcf.gz.csi", checkIfExists: true) - ]) - ref_panel = Channel.of([ - file(params.modules_testdata_base_path + "delete_me/glimpse/1000GP.chr21.noNA12878.s.bcf", checkIfExists: true), - file(params.modules_testdata_base_path + "delete_me/glimpse/1000GP.chr21.noNA12878.s.bcf.csi", checkIfExists: true) - ]) - ch_map = Channel.of([ - file(params.modules_testdata_base_path + "delete_me/glimpse/chr21.b38.gmap.gz", checkIfExists: true), - ]) - - input[0] = input_vcf - | combine(ch_sample) - | combine(region) - | combine(ref_panel) - | combine(ch_map) - """ - } - } - run("BCFTOOLS_INDEX") { - script "../../../bcftools/index/main.nf" - process { - """ - input[0] = GLIMPSE_PHASE.out.phased_variants - """ - } - } - } when { process { """ - allele_freq = Channel.fromList([ - file(params.modules_testdata_base_path + "delete_me/glimpse/1000GP.chr21.noNA12878.s.sites.vcf.gz",checkIfExists:true), - file(params.modules_testdata_base_path + "delete_me/glimpse/1000GP.chr21.noNA12878.s.sites.vcf.gz.csi",checkIfExists:true) - ]).collect() - truth = Channel.fromList([ - file(params.modules_testdata_base_path + "delete_me/glimpse/NA12878.chr21.s.bcf",checkIfExists:true), - file(params.modules_testdata_base_path + "delete_me/glimpse/NA12878.chr21.s.bcf.csi",checkIfExists:true) - ]).collect() - estimate = GLIMPSE_PHASE.out.phased_variants - | join (BCFTOOLS_INDEX.out.csi) - input[0] = estimate - | combine (allele_freq) - | combine (truth) - | combine (["chr21"]) - input[1] = [] - input[2] = [] + input[0] = channel.of([ + [ 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), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.sites.vcf.gz",checkIfExists:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.sites.vcf.gz.csi",checkIfExists:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz",checkIfExists:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi",checkIfExists:true), + "chr21" + ]) + input[1] = 0.7 + input[2] = 3 input[3] = [] """ } @@ -78,12 +37,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot( - process.out.errors_cal, - process.out.errors_spl, - process.out.rsquare_spl, - process.out.versions - ).match() } + { assert snapshot(process.out).match() } ) } diff --git a/modules/nf-core/glimpse/concordance/tests/main.nf.test.snap b/modules/nf-core/glimpse/concordance/tests/main.nf.test.snap index 1fb0ee9c51de..81d2744ff198 100644 --- a/modules/nf-core/glimpse/concordance/tests/main.nf.test.snap +++ b/modules/nf-core/glimpse/concordance/tests/main.nf.test.snap @@ -1,38 +1,99 @@ { "test_glimpse_concordance": { "content": [ - [ - [ - { - "id": "input" - }, - "input.error.cal.txt.gz:md5,15c6a120d9fd3ac8c0ff6a6aedc76571" + { + "0": [ + [ + { + "id": "NA12878" + }, + "NA12878.error.cal.txt.gz:md5,b4af39e7acfebd69f2fe5fa496551a32" + ] + ], + "1": [ + [ + { + "id": "NA12878" + }, + "NA12878.error.grp.txt.gz:md5,069e311f252ff6b6e748a68ce0bcb499" + ] + ], + "2": [ + [ + { + "id": "NA12878" + }, + "NA12878.error.spl.txt.gz:md5,284843acf1662f2aeafc6fe5c47e629f" + ] + ], + "3": [ + [ + { + "id": "NA12878" + }, + "NA12878.rsquare.grp.txt.gz:md5,06c70a1e2047710d6752b9d98e45cea0" + ] + ], + "4": [ + [ + { + "id": "NA12878" + }, + "NA12878.rsquare.spl.txt.gz:md5,30a00f0b1de47fd63414d819b4304ded" + ] + ], + "5": [ + "versions.yml:md5,b6c06f9736c60f9f548c3c082b522025" + ], + "errors_cal": [ + [ + { + "id": "NA12878" + }, + "NA12878.error.cal.txt.gz:md5,b4af39e7acfebd69f2fe5fa496551a32" + ] + ], + "errors_grp": [ + [ + { + "id": "NA12878" + }, + "NA12878.error.grp.txt.gz:md5,069e311f252ff6b6e748a68ce0bcb499" + ] + ], + "errors_spl": [ + [ + { + "id": "NA12878" + }, + "NA12878.error.spl.txt.gz:md5,284843acf1662f2aeafc6fe5c47e629f" + ] + ], + "rsquare_grp": [ + [ + { + "id": "NA12878" + }, + "NA12878.rsquare.grp.txt.gz:md5,06c70a1e2047710d6752b9d98e45cea0" + ] + ], + "rsquare_spl": [ + [ + { + "id": "NA12878" + }, + "NA12878.rsquare.spl.txt.gz:md5,30a00f0b1de47fd63414d819b4304ded" + ] + ], + "versions": [ + "versions.yml:md5,b6c06f9736c60f9f548c3c082b522025" ] - ], - [ - [ - { - "id": "input" - }, - "input.error.spl.txt.gz:md5,35cb463e8db41e2180f21941ab0324e0" - ] - ], - [ - [ - { - "id": "input" - }, - "input.rsquare.spl.txt.gz:md5,55659f466775d828ee1ba723464bb460" - ] - ], - [ - "versions.yml:md5,f79c864118d03a4afa93082c46c0d608" - ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-15T12:50:35.203335" + "timestamp": "2025-11-27T11:08:34.841155791" } } \ No newline at end of file diff --git a/modules/nf-core/glimpse/concordance/tests/nextflow.config b/modules/nf-core/glimpse/concordance/tests/nextflow.config new file mode 100644 index 000000000000..4ab697f9d031 --- /dev/null +++ b/modules/nf-core/glimpse/concordance/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: GLIMPSE_CONCORDANCE { + ext.args = "--gt-validation --gt-target" + } +} diff --git a/modules/nf-core/glimpse/ligate/main.nf b/modules/nf-core/glimpse/ligate/main.nf index fbef5738e8f3..a62b24d62c85 100644 --- a/modules/nf-core/glimpse/ligate/main.nf +++ b/modules/nf-core/glimpse/ligate/main.nf @@ -22,7 +22,7 @@ process GLIMPSE_LIGATE { def prefix = task.ext.prefix ?: "${meta.id}" def suffix = task.ext.suffix ?: "vcf.gz" """ - printf "%s\\n" $input_list | tr -d '[],' > all_files.txt + printf "%s\\n" $input_list | tr -d '[],' | sort -V > all_files.txt GLIMPSE_ligate \\ $args \\ @@ -31,8 +31,8 @@ process GLIMPSE_LIGATE { --output ${prefix}.${suffix} cat <<-END_VERSIONS > versions.yml - "${task.process}": - glimpse: "\$(GLIMPSE_ligate --help | sed -nr '/Version/p' | grep -o -E '([0-9]+.){1,2}[0-9]')" + "${task.process}": + glimpse: "\$(GLIMPSE_ligate --help | sed -nr '/Version/p' | grep -o -E '([0-9]+.){1,2}[0-9]')" END_VERSIONS """ diff --git a/modules/nf-core/glimpse/ligate/tests/main.nf.test b/modules/nf-core/glimpse/ligate/tests/main.nf.test index 7289fc91acce..685deb3466eb 100644 --- a/modules/nf-core/glimpse/ligate/tests/main.nf.test +++ b/modules/nf-core/glimpse/ligate/tests/main.nf.test @@ -17,27 +17,30 @@ nextflow_process { script "../../phase/main.nf" process { """ - ch_sample = Channel.of('NA12878 2').collectFile(name: 'sampleinfos.txt') - region = Channel.fromList([ - ["chr21:16600000-16750000","chr21:16650000-16700000"], - ["chr21:16650000-16800000","chr21:16700000-16750000"] - ]) - input_vcf = Channel.of([ + ch_sample = channel.of('NA12878 2').collectFile(name: 'sampleinfos.txt') + region = channel.of( + ["chr21:16570065-16597215","chr21:16570065-16592216"], + ["chr21:16587172-16609999","chr21:16592229-16609999"] + ) + input_vcf = channel.of([ [ id:'input'], // meta map - file(params.modules_testdata_base_path + "delete_me/glimpse/NA12878.chr21.s.1x.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "delete_me/glimpse/NA12878.chr21.s.1x.vcf.gz.csi", checkIfExists: true) + 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) ]) - ref_panel = Channel.of([ - file(params.modules_testdata_base_path + "delete_me/glimpse/1000GP.chr21.noNA12878.s.bcf", checkIfExists: true), - file(params.modules_testdata_base_path + "delete_me/glimpse/1000GP.chr21.noNA12878.s.bcf.csi", checkIfExists: true) + ref_panel = channel.of([ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz.csi", checkIfExists: true) ]) - ch_map = Channel.of([ - file(params.modules_testdata_base_path + "delete_me/glimpse/chr21.b38.gmap.gz", checkIfExists: true), + ch_map = channel.of([ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr21.glimpse.map", checkIfExists: true) ]) input[0] = input_vcf | combine(ch_sample) | combine(region) + | map { meta, vcf, index, sample, regionI, regionO -> + [[id: meta.id, region : regionI], vcf, index, sample, regionI, regionO] + } | combine(ref_panel) | combine(ch_map) """ @@ -57,20 +60,28 @@ nextflow_process { process { """ input[0] = GLIMPSE_PHASE.out.phased_variants - | groupTuple() - | join (BCFTOOLS_INDEX.out.csi.groupTuple()) + .join(BCFTOOLS_INDEX.out.csi) + .map{ meta, vcf, index -> [meta.subMap("id"), vcf, index]} + .groupTuple() """ } } then { - def lines = path(process.out.merged_variants.get(0).get(1)).linesGzip.last() assertAll( { assert process.success }, - { assert snapshot(process.out.versions).match("versions") }, - { assert snapshot(lines).match("ligate") } + { assert snapshot( + process.out.merged_variants.collect { + meta, vcf -> [ + meta, + file(vcf).name, + path(vcf).vcf.summary, + path(vcf).vcf.variantsMD5 + ] + }, + ["versions": process.out.versions] + ).match() } ) } - } } diff --git a/modules/nf-core/glimpse/ligate/tests/main.nf.test.snap b/modules/nf-core/glimpse/ligate/tests/main.nf.test.snap index 8eec13282905..7a1be2fc484d 100644 --- a/modules/nf-core/glimpse/ligate/tests/main.nf.test.snap +++ b/modules/nf-core/glimpse/ligate/tests/main.nf.test.snap @@ -1,16 +1,26 @@ { - "versions": { + "test_glimpse_ligate": { "content": [ [ - "versions.yml:md5,0cc9dfe9c9c1087666c418aa3379cf85" - ] + [ + { + "id": "input" + }, + "input.vcf.gz", + "VcfFile [chromosomes=[chr21], sampleCount=1, variantCount=836, phased=false, phasedAutodetect=false]", + "bcb1deefc22f80c32d5ca5cedb56cd75" + ] + ], + { + "versions": [ + "versions.yml:md5,bd8cbcd55d6d05c480747657852fad35" + ] + } ], - "timestamp": "2023-10-17T11:56:25.087453677" - }, - "ligate": { - "content": [ - "chr21\t16799989\t21:16799989:T:C\tT\tC\t.\t.\tRAF=0.000468897;AF=0;INFO=1\tGT:DS:GP:HS\t0/0:0:1,0,0:0" - ], - "timestamp": "2023-10-17T11:56:25.116120487" + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-26T20:11:05.020643957" } } \ No newline at end of file diff --git a/modules/nf-core/glimpse/phase/main.nf b/modules/nf-core/glimpse/phase/main.nf index 53487557ada8..e5ba79718880 100644 --- a/modules/nf-core/glimpse/phase/main.nf +++ b/modules/nf-core/glimpse/phase/main.nf @@ -46,6 +46,7 @@ process GLIMPSE_PHASE { stub: def prefix = task.ext.prefix ?: "${meta.id}_${input_region.replace(":","_")}" def suffix = task.ext.suffix ?: "vcf.gz" + """ touch ${prefix}.${suffix} diff --git a/modules/nf-core/glimpse/phase/tests/main.nf.test b/modules/nf-core/glimpse/phase/tests/main.nf.test index 5c92cb1fc64f..583005c9184b 100644 --- a/modules/nf-core/glimpse/phase/tests/main.nf.test +++ b/modules/nf-core/glimpse/phase/tests/main.nf.test @@ -13,31 +13,29 @@ nextflow_process { when { process { """ - ch_sample = Channel.of([sample:'present']) - | combine(Channel.of('NA12878 2').collectFile(name: 'sampleinfos.txt')) - | concat(Channel.of([[sample: 'absent'], []])) - region = Channel.fromList([ - ["chr21:16600000-16750000","chr21:16650000-16700000"], - ["chr21:16650000-16800000","chr21:16700000-16750000"] + ch_sample = Channel.of('NA12878 2').collectFile(name: 'sampleinfos.txt') + region = channel.fromList([ + ["chr21:16570065-16597215","chr21:16570065-16592216"], + ["chr21:16587172-16609999","chr21:16592229-16609999"] ]) - input_vcf = Channel.of([ + input_vcf = channel.of([ [ id:'input'], // meta map - file(params.modules_testdata_base_path + "delete_me/glimpse/NA12878.chr21.s.1x.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "delete_me/glimpse/NA12878.chr21.s.1x.vcf.gz.csi", checkIfExists: true) + 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) ]) - ref_panel = Channel.of([ - file(params.modules_testdata_base_path + "delete_me/glimpse/1000GP.chr21.noNA12878.s.bcf", checkIfExists: true), - file(params.modules_testdata_base_path + "delete_me/glimpse/1000GP.chr21.noNA12878.s.bcf.csi", checkIfExists: true) + ref_panel = channel.of([ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz.csi", checkIfExists: true) ]) - ch_map = Channel.of([ - file(params.modules_testdata_base_path + "delete_me/glimpse/chr21.b38.gmap.gz", checkIfExists: true), + ch_map = channel.of([ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr21.glimpse.map", checkIfExists: true) ]) input[0] = input_vcf | combine(ch_sample) | combine(region) - | map { meta, vcf, index, metaS, sample, regionI, regionO -> - [[id: meta.id + "_" + metaS.sample, region : regionI], vcf, index, sample, regionI, regionO] + | map { meta, vcf, index, sample, regionI, regionO -> + [[id: meta.id, region : regionI], vcf, index, sample, regionI, regionO] } | combine(ref_panel) | combine(ch_map) @@ -46,20 +44,17 @@ nextflow_process { } then { - String targetFileName = "input_present_chr21_16650000-16800000.vcf.gz" - File selectedFile = process.out.phased_variants.stream() - .filter(vector -> vector.size() > 1) - .map(vector -> new File(vector.get(1).toString())) - .filter(file -> file.getName().equals(targetFileName)) - .findFirst() - .orElse(null) - String selectedFilename = selectedFile != null ? selectedFile.getPath() : null - def lines = path(selectedFilename).linesGzip.last() assertAll( { assert process.success }, - { assert snapshot(process.out.versions).match("versions") }, - { assert process.out.phased_variants.size() == 4}, - { assert snapshot(lines).match("imputed") } + { assert snapshot( + process.out.phased_variants.collect{ meta, vcf -> [ + meta, + file(vcf).name, + path(vcf).vcf.summary, + path(vcf).vcf.variantsMD5 + ] }, + process.out.versions + ).match() } ) } diff --git a/modules/nf-core/glimpse/phase/tests/main.nf.test.snap b/modules/nf-core/glimpse/phase/tests/main.nf.test.snap index d61cf86ece4d..1ba021845c94 100644 --- a/modules/nf-core/glimpse/phase/tests/main.nf.test.snap +++ b/modules/nf-core/glimpse/phase/tests/main.nf.test.snap @@ -1,19 +1,35 @@ { - "versions": { + "test_glimpse_phase": { "content": [ [ - "versions.yml:md5,b24f49b2f5989a1f7da32c195334e96b", - "versions.yml:md5,b24f49b2f5989a1f7da32c195334e96b", + [ + { + "id": "input", + "region": "chr21:16570065-16597215" + }, + "input_chr21_16570065-16597215.vcf.gz", + "VcfFile [chromosomes=[chr21], sampleCount=1, variantCount=563, phased=false, phasedAutodetect=false]", + "307c42e67924110b165f1fff0e5c14a" + ], + [ + { + "id": "input", + "region": "chr21:16587172-16609999" + }, + "input_chr21_16587172-16609999.vcf.gz", + "VcfFile [chromosomes=[chr21], sampleCount=1, variantCount=459, phased=false, phasedAutodetect=false]", + "b138aad7ca677f696b7635802d3be82e" + ] + ], + [ "versions.yml:md5,b24f49b2f5989a1f7da32c195334e96b", "versions.yml:md5,b24f49b2f5989a1f7da32c195334e96b" ] ], - "timestamp": "2023-10-17T15:27:55.512415434" - }, - "imputed": { - "content": [ - "chr21\t16799989\t21:16799989:T:C\tT\tC\t.\t.\tRAF=0.000468897;AF=0;INFO=1;BUF=1\tGT:DS:GP:HS\t0/0:0:1,0,0:0" - ], - "timestamp": "2023-10-17T15:27:55.99820664" + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-26T20:07:25.309393538" } } \ No newline at end of file diff --git a/modules/nf-core/glimpse/sample/main.nf b/modules/nf-core/glimpse/sample/main.nf index c05296812abc..0fcfb6b4f2f9 100644 --- a/modules/nf-core/glimpse/sample/main.nf +++ b/modules/nf-core/glimpse/sample/main.nf @@ -8,7 +8,7 @@ process GLIMPSE_SAMPLE { 'biocontainers/glimpse-bio:1.1.1--hce55b13_1' }" input: - tuple val(meta), path(input) + tuple val(meta), path(input), path(index) output: tuple val(meta), path("*.{vcf,bcf,vcf.gz,bcf.gz}"), emit: haplo_sampled @@ -38,6 +38,7 @@ process GLIMPSE_SAMPLE { stub: def prefix = task.ext.prefix ?: "${meta.id}" def suffix = task.ext.suffix ?: "vcf.gz" + """ touch ${prefix}.${suffix} diff --git a/modules/nf-core/glimpse/sample/meta.yml b/modules/nf-core/glimpse/sample/meta.yml index ebb1b71cd559..2dd508a56348 100644 --- a/modules/nf-core/glimpse/sample/meta.yml +++ b/modules/nf-core/glimpse/sample/meta.yml @@ -22,9 +22,14 @@ input: e.g. [ id:'test', single_end:false ] - input: type: file - description: VCF/BCF file generated using GLIMPSE ligate + description: Imputed VCF/BCF file pattern: "*.{vcf,bcf,vcf.gz,bcf.gz}" ontologies: [] + - index: + type: file + description: Index file of the input VCF/BCF file. + pattern: "*.{vcf.gz.csi,bcf.gz.csi}" + ontologies: [] output: haplo_sampled: - - meta: diff --git a/modules/nf-core/glimpse/sample/tests/main.nf.test b/modules/nf-core/glimpse/sample/tests/main.nf.test index 494c35296fea..cac8ac5159ce 100644 --- a/modules/nf-core/glimpse/sample/tests/main.nf.test +++ b/modules/nf-core/glimpse/sample/tests/main.nf.test @@ -4,59 +4,78 @@ nextflow_process { script "../main.nf" process "GLIMPSE_SAMPLE" + config "./nextflow.config" + tag "modules" tag "modules_nfcore" tag "glimpse" tag "glimpse/sample" tag "glimpse/phase" + tag "bcftools" + tag "bcftools/index" test("test_glimpse_sample") { - config "./nextflow.config" setup { run("GLIMPSE_PHASE") { script "../../phase/main.nf" process { """ - ch_sample = Channel.of('NA12878 2').collectFile(name: 'sampleinfos.txt') - region = Channel.fromList([ - ["chr21:16600000-16750000","chr21:16650000-16700000"] - ]) - input_vcf = Channel.of([ + ch_sample = Channel.of('NA12878 2').collectFile(name: 'sampleinfos.txt') + region = channel.of(["chr21:16570000-16610000","chr21:16570000-16610000"]) + input_vcf = channel.of([ [ id:'input'], // meta map - file(params.modules_testdata_base_path + "delete_me/glimpse/NA12878.chr21.s.1x.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "delete_me/glimpse/NA12878.chr21.s.1x.vcf.gz.csi", checkIfExists: true) + 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) ]) - ref_panel = Channel.of([ - file(params.modules_testdata_base_path + "delete_me/glimpse/1000GP.chr21.noNA12878.s.bcf", checkIfExists: true), - file(params.modules_testdata_base_path + "delete_me/glimpse/1000GP.chr21.noNA12878.s.bcf.csi", checkIfExists: true) + ref_panel = channel.of([ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz.csi", checkIfExists: true) ]) - ch_map = Channel.of([ - file(params.modules_testdata_base_path + "delete_me/glimpse/chr21.b38.gmap.gz", checkIfExists: true), + ch_map = channel.of([ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr21.glimpse.map", checkIfExists: true) ]) input[0] = input_vcf | combine(ch_sample) | combine(region) + | map { meta, vcf, index, sample, regionI, regionO -> + [[id: meta.id, region : regionI], vcf, index, sample, regionI, regionO] + } | combine(ref_panel) | combine(ch_map) """ } } + run("BCFTOOLS_INDEX") { + script "../../../bcftools/index/main.nf" + process { + """ + input[0] = GLIMPSE_PHASE.out.phased_variants + """ + } + } } when { process { """ input[0] = GLIMPSE_PHASE.out.phased_variants + .join(BCFTOOLS_INDEX.out.csi) """ } } then { - def lines = path(process.out.haplo_sampled.get(0).get(1)).linesGzip.last() assertAll( { assert process.success }, - { assert snapshot(process.out.versions).match("versions") }, - { assert snapshot(lines).match("sampled") } + { assert snapshot( + process.out.haplo_sampled.collect{ meta, vcf -> [ + meta, + file(vcf).name, + path(vcf).vcf.summary, + path(vcf).vcf.variantsMD5 + ] }, + process.out.versions + ).match() } ) } diff --git a/modules/nf-core/glimpse/sample/tests/main.nf.test.snap b/modules/nf-core/glimpse/sample/tests/main.nf.test.snap index 5892f99be2c7..b36088af4fcc 100644 --- a/modules/nf-core/glimpse/sample/tests/main.nf.test.snap +++ b/modules/nf-core/glimpse/sample/tests/main.nf.test.snap @@ -1,16 +1,25 @@ { - "versions": { + "test_glimpse_sample": { "content": [ + [ + [ + { + "id": "input", + "region": "chr21:16570000-16610000" + }, + "input.vcf.gz", + "VcfFile [chromosomes=[chr21], sampleCount=1, variantCount=836, phased=true, phasedAutodetect=true]", + "98729a14199e84f9da0a80591d76b280" + ] + ], [ "versions.yml:md5,6ae83ef08ccde17c6dc248b9133c0fb8" ] ], - "timestamp": "2023-10-17T16:00:45.692964159" - }, - "sampled": { - "content": [ - "chr21\t16749965\t21:16749965:T:A\tT\tA\t.\t.\tRAF=0.000312598;AF=0.001;INFO=0.001;BUF=1\tGT\t0|0" - ], - "timestamp": "2023-10-17T16:00:45.81432328" + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-26T20:15:47.765405625" } } \ No newline at end of file diff --git a/modules/nf-core/glimpse2/chunk/tests/main.nf.test b/modules/nf-core/glimpse2/chunk/tests/main.nf.test index 0b6545e1fb5c..14ca3190222f 100644 --- a/modules/nf-core/glimpse2/chunk/tests/main.nf.test +++ b/modules/nf-core/glimpse2/chunk/tests/main.nf.test @@ -43,7 +43,7 @@ nextflow_process { 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", - file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/phaseimpute/hum_data/reference_genome/GRCh38_chr22.glimpse.map", checkIfExists: true) + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.glimpse.map", checkIfExists: true) ] input[1]= "recursive" """ diff --git a/modules/nf-core/glimpse2/chunk/tests/main.nf.test.snap b/modules/nf-core/glimpse2/chunk/tests/main.nf.test.snap index 2a380092cb8a..d36e35b73040 100644 --- a/modules/nf-core/glimpse2/chunk/tests/main.nf.test.snap +++ b/modules/nf-core/glimpse2/chunk/tests/main.nf.test.snap @@ -77,7 +77,7 @@ { "id": "test" }, - "test.txt:md5,bf269cf00892ea2a9650817703805608" + "test.txt:md5,3bfef0fe24564dd3f759ee390345970a" ] ], [ @@ -85,9 +85,9 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-20T10:09:14.973419042" + "timestamp": "2025-11-26T20:44:36.241361838" } } \ No newline at end of file diff --git a/modules/nf-core/glimpse2/concordance/main.nf b/modules/nf-core/glimpse2/concordance/main.nf index a542993d69c1..945c3dd6a0e4 100644 --- a/modules/nf-core/glimpse2/concordance/main.nf +++ b/modules/nf-core/glimpse2/concordance/main.nf @@ -77,7 +77,7 @@ process GLIMPSE2_CONCORDANCE { cat <<-END_VERSIONS > versions.yml "${task.process}": - glimpse: "\$(GLIMPSE_concordance --help | sed -nr '/Version/p' | grep -o -E '([0-9]+.){1,2}[0-9]')" + glimpse2: "\$(GLIMPSE2_concordance --help | sed -nr '/Version/p' | grep -o -E '([0-9]+.){1,2}[0-9]' | head -1)" END_VERSIONS """ } diff --git a/modules/nf-core/glimpse2/concordance/tests/main.nf.test b/modules/nf-core/glimpse2/concordance/tests/main.nf.test index d1c68bc208d0..f37c3da863f7 100644 --- a/modules/nf-core/glimpse2/concordance/tests/main.nf.test +++ b/modules/nf-core/glimpse2/concordance/tests/main.nf.test @@ -3,6 +3,9 @@ nextflow_process { name "Test Process GLIMPSE2_CONCORDANCE" script "../main.nf" process "GLIMPSE2_CONCORDANCE" + + config "./nextflow.config" + tag "glimpse2" tag "glimpse2/concordance" tag "glimpse2/phase" @@ -11,22 +14,21 @@ nextflow_process { tag "modules" test("test glimpse2 concordance") { - config "./nextflow.config" when { params { - glimpse2_concordance_args = "--gt-val --af-tag AF" + glimpse2_concordance_args = "--gt-val --af-tag AF --seed 1" } process { """ target = Channel.of([ [id: "input"], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz",checkIfExists:true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi",checkIfExists:true) + 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) ]) truth = Channel.of([ - 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_GIAB.chr22.vcf.gz.csi",checkIfExists:true) + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz",checkIfExists:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi",checkIfExists:true) ]) allele_freq = Channel.of([ file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.sites.vcf.gz",checkIfExists:true), @@ -47,22 +49,13 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot( - process.out.errors_cal.collect{ file(it[1]).name }, - process.out.errors_grp.collect{ file(it[1]).name }, - process.out.errors_spl.collect{ file(it[1]).name }, - process.out.rsquare_grp.collect{ file(it[1]).name }, - process.out.rsquare_spl.collect{ file(it[1]).name }, - process.out.versions - ).match() } + { assert snapshot(process.out).match() } ) } } test("test list of region and rsquare per site") { - config "./nextflow.config" - when { params { glimpse2_concordance_args = "--gt-val --af-tag AF --out-r2-per-site" @@ -71,12 +64,12 @@ nextflow_process { """ target = Channel.of([ [id: "input"], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz",checkIfExists:true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi",checkIfExists:true) + 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) ]) truth = Channel.of([ - 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_GIAB.chr22.vcf.gz.csi",checkIfExists:true) + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz",checkIfExists:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi",checkIfExists:true) ]) allele_freq = Channel.of([ file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.sites.vcf.gz",checkIfExists:true), @@ -98,15 +91,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot( - process.out.errors_cal.collect{ file(it[1]).name }, - process.out.errors_grp.collect{ file(it[1]).name }, - process.out.errors_spl.collect{ file(it[1]).name }, - process.out.rsquare_grp.collect{ file(it[1]).name }, - process.out.rsquare_spl.collect{ file(it[1]).name }, - process.out.rsquare_per_site.collect{ file(it[1]).name }, - process.out.versions - ).match() } + { assert snapshot(process.out).match() } ) } diff --git a/modules/nf-core/glimpse2/concordance/tests/main.nf.test.snap b/modules/nf-core/glimpse2/concordance/tests/main.nf.test.snap index 5e81d44e2f04..b40e39bc825d 100644 --- a/modules/nf-core/glimpse2/concordance/tests/main.nf.test.snap +++ b/modules/nf-core/glimpse2/concordance/tests/main.nf.test.snap @@ -1,59 +1,218 @@ { "test glimpse2 concordance": { "content": [ - [ - "input.error.cal.txt.gz" - ], - [ - "input.error.grp.txt.gz" - ], - [ - "input.error.spl.txt.gz" - ], - [ - "input.rsquare.grp.txt.gz" - ], - [ - "input.rsquare.spl.txt.gz" - ], - [ - "versions.yml:md5,ba729289bab6b9fbb8c36a620c86bb82" - ] + { + "0": [ + [ + { + "id": "input" + }, + "input.error.cal.txt.gz:md5,605cf14649d768c07a6c5cff15aea26a" + ] + ], + "1": [ + [ + { + "id": "input" + }, + "input.error.grp.txt.gz:md5,bdbe0131aa4d239de367bbb18e3c3327" + ] + ], + "2": [ + [ + { + "id": "input" + }, + "input.error.spl.txt.gz:md5,034c0ecc19243d70e9cfda9083472763" + ] + ], + "3": [ + [ + { + "id": "input" + }, + "input.rsquare.grp.txt.gz:md5,d70d53a5012b161ba4de65cd48dcac67" + ] + ], + "4": [ + [ + { + "id": "input" + }, + "input.rsquare.spl.txt.gz:md5,9f0f2f13b8ea8597a83c35d578476989" + ] + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,ba729289bab6b9fbb8c36a620c86bb82" + ], + "errors_cal": [ + [ + { + "id": "input" + }, + "input.error.cal.txt.gz:md5,605cf14649d768c07a6c5cff15aea26a" + ] + ], + "errors_grp": [ + [ + { + "id": "input" + }, + "input.error.grp.txt.gz:md5,bdbe0131aa4d239de367bbb18e3c3327" + ] + ], + "errors_spl": [ + [ + { + "id": "input" + }, + "input.error.spl.txt.gz:md5,034c0ecc19243d70e9cfda9083472763" + ] + ], + "rsquare_grp": [ + [ + { + "id": "input" + }, + "input.rsquare.grp.txt.gz:md5,d70d53a5012b161ba4de65cd48dcac67" + ] + ], + "rsquare_per_site": [ + + ], + "rsquare_spl": [ + [ + { + "id": "input" + }, + "input.rsquare.spl.txt.gz:md5,9f0f2f13b8ea8597a83c35d578476989" + ] + ], + "versions": [ + "versions.yml:md5,ba729289bab6b9fbb8c36a620c86bb82" + ] + } ], "meta": { - "nf-test": "0.9.1", - "nextflow": "24.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-12-03T16:22:35.440086384" + "timestamp": "2025-11-27T11:09:00.725735403" }, "test list of region and rsquare per site": { "content": [ - [ - "input.error.cal.txt.gz" - ], - [ - "input.error.grp.txt.gz" - ], - [ - "input.error.spl.txt.gz" - ], - [ - "input.rsquare.grp.txt.gz" - ], - [ - "input.rsquare.spl.txt.gz" - ], - [ - "input_r2_sites.txt.gz" - ], - [ - "versions.yml:md5,ba729289bab6b9fbb8c36a620c86bb82" - ] + { + "0": [ + [ + { + "id": "input" + }, + "input.error.cal.txt.gz:md5,3a4753237fd8174ff46fb91bba712d5c" + ] + ], + "1": [ + [ + { + "id": "input" + }, + "input.error.grp.txt.gz:md5,382dd127002f43716563a71a2b693de4" + ] + ], + "2": [ + [ + { + "id": "input" + }, + "input.error.spl.txt.gz:md5,61a1133643ae5b0dc44ba76976b0bcce" + ] + ], + "3": [ + [ + { + "id": "input" + }, + "input.rsquare.grp.txt.gz:md5,974a8c3188112716482103b8508ed109" + ] + ], + "4": [ + [ + { + "id": "input" + }, + "input.rsquare.spl.txt.gz:md5,9f0f2f13b8ea8597a83c35d578476989" + ] + ], + "5": [ + [ + { + "id": "input" + }, + "input_r2_sites.txt.gz:md5,f65d7df3b887a4aade33a0b7b60bcca4" + ] + ], + "6": [ + "versions.yml:md5,ba729289bab6b9fbb8c36a620c86bb82" + ], + "errors_cal": [ + [ + { + "id": "input" + }, + "input.error.cal.txt.gz:md5,3a4753237fd8174ff46fb91bba712d5c" + ] + ], + "errors_grp": [ + [ + { + "id": "input" + }, + "input.error.grp.txt.gz:md5,382dd127002f43716563a71a2b693de4" + ] + ], + "errors_spl": [ + [ + { + "id": "input" + }, + "input.error.spl.txt.gz:md5,61a1133643ae5b0dc44ba76976b0bcce" + ] + ], + "rsquare_grp": [ + [ + { + "id": "input" + }, + "input.rsquare.grp.txt.gz:md5,974a8c3188112716482103b8508ed109" + ] + ], + "rsquare_per_site": [ + [ + { + "id": "input" + }, + "input_r2_sites.txt.gz:md5,f65d7df3b887a4aade33a0b7b60bcca4" + ] + ], + "rsquare_spl": [ + [ + { + "id": "input" + }, + "input.rsquare.spl.txt.gz:md5,9f0f2f13b8ea8597a83c35d578476989" + ] + ], + "versions": [ + "versions.yml:md5,ba729289bab6b9fbb8c36a620c86bb82" + ] + } ], "meta": { - "nf-test": "0.9.1", - "nextflow": "24.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-12-03T16:26:35.009071185" + "timestamp": "2025-11-27T11:21:10.279509256" } } \ No newline at end of file diff --git a/modules/nf-core/glimpse2/ligate/tests/main.nf.test b/modules/nf-core/glimpse2/ligate/tests/main.nf.test index 1298e7b91c97..1ca94473aaa9 100644 --- a/modules/nf-core/glimpse2/ligate/tests/main.nf.test +++ b/modules/nf-core/glimpse2/ligate/tests/main.nf.test @@ -18,14 +18,15 @@ nextflow_process { script "../../phase/main.nf" process { """ - input_vcf = Channel.of([ + input_vcf = channel.of([ [ id:'input' ], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), - [], [], - "chr22:16600000-16800000", - "chr22:16650000-16750000" - ]) + 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), + [], [] + ]).combine(channel.of( + ["chr22:16570065-16597215", "chr22:16570065-16592216"], + ["chr22:16587172-16609999", "chr22:16592229-16609999"] + )) ref_panel = Channel.of([ file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz", checkIfExists:true), @@ -36,9 +37,12 @@ nextflow_process { // [meta, vcf, index, sample_infos, regionin, regionout,ref, index, map] [meta, fasta, fai] input[0] = input_vcf + .map { meta, vcf, index, list, sample, regionI, regionO -> + [[id: meta.id, region : regionI], vcf, index, list, sample, regionI, regionO] + } .combine(ref_panel) .combine(map_file) - input[1] = Channel.of([[],[],[]]) + input[1] = Channel.of([[],[],[]]).collect() """ } } @@ -56,8 +60,9 @@ nextflow_process { process { """ input[0] = GLIMPSE2_PHASE.out.phased_variants - | groupTuple() - | join (BCFTOOLS_INDEX.out.csi.groupTuple()) + .join(BCFTOOLS_INDEX.out.csi) + .map{ meta, vcf, index -> [meta.subMap("id"), vcf, index]} + .groupTuple() """ } } @@ -67,7 +72,12 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.versions, - process.out.merged_variants.collect{ path(it[1]).vcf.variantsMD5} + process.out.merged_variants.collect{ meta, vcf -> [ + meta, + file(vcf).name, + path(vcf).vcf.summary, + path(vcf).vcf.variantsMD5 + ] } ).match() }, ) } @@ -80,8 +90,8 @@ nextflow_process { """ input[0] = Channel.of([ [ id:'input' ], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + 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), ]) """ } @@ -90,10 +100,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot( - process.out, - path(process.out.versions[0]).yaml, - ).match() }, + { assert snapshot(process.out).match() }, ) } } diff --git a/modules/nf-core/glimpse2/ligate/tests/main.nf.test.snap b/modules/nf-core/glimpse2/ligate/tests/main.nf.test.snap index 995bcfb0eb5b..4422e31d2a5a 100644 --- a/modules/nf-core/glimpse2/ligate/tests/main.nf.test.snap +++ b/modules/nf-core/glimpse2/ligate/tests/main.nf.test.snap @@ -5,14 +5,21 @@ "versions.yml:md5,44addcaef4965ff6409a8293c5bcad84" ], [ - "8730c5450f0c32d72c6d5cb4eb02b38b" + [ + { + "id": "input" + }, + "input.vcf.gz", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=903, phased=true, phasedAutodetect=true]", + "bfeec64e4bbd1211d3dd284aff482995" + ] ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-19T23:17:50.793909707" + "timestamp": "2025-11-26T20:54:57.8806397" }, "Should run glimpse ligate -- stub": { "content": [ @@ -39,17 +46,12 @@ "versions": [ "versions.yml:md5,44addcaef4965ff6409a8293c5bcad84" ] - }, - { - "GLIMPSE2_LIGATE": { - "glimpse2": "2.0.0" - } } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-19T23:19:24.515887682" + "timestamp": "2025-11-26T20:46:48.337059937" } -} +} \ No newline at end of file diff --git a/modules/nf-core/glimpse2/phase/tests/main.nf.test b/modules/nf-core/glimpse2/phase/tests/main.nf.test index c7b2d46a2d47..c7dfcd7ed827 100644 --- a/modules/nf-core/glimpse2/phase/tests/main.nf.test +++ b/modules/nf-core/glimpse2/phase/tests/main.nf.test @@ -17,27 +17,27 @@ nextflow_process { when { process { """ - input_vcf = Channel.of([ + input_vcf = channel.of([ [ id:'input' ], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + 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), [], [], "chr22:16600000-16800000", "chr22:16650000-16750000" ]) - ref_panel = Channel.of([ + ref_panel = 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), ]) - map_file = Channel.of([[]]) + map_file = channel.of([[]]) // [meta, vcf, index, sample_infos, regionin, regionout,ref, index, map] [meta, fasta, fai] input[0] = input_vcf .combine(ref_panel) .combine(map_file) - input[1] = Channel.of([[],[],[]]) + input[1] = channel.of([[],[],[]]) """ } } @@ -46,7 +46,13 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - path(process.out.phased_variants[0][1]).vcf.variantsMD5, + process.out.phased_variants.collect{ meta, vcf -> [ + meta, + file(vcf).name, + path(vcf).vcf.summary, + path(vcf).vcf.variantsMD5 + ]}, + process.out.stats_coverage, process.out.versions ).match()} ) @@ -58,27 +64,27 @@ nextflow_process { when { process { """ - input_bam = Channel.of([ + input_bam = channel.of([ [id:'input'], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam.bai", checkIfExists: true), + 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), [], [], "chr22:16600000-16800000", "chr22:16650000-16750000", ]) - ref_panel = Channel.of([ + ref_panel = 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), ]) - map_file = Channel.of([[]]) + map_file = channel.of([[]]) // [meta, vcf, index, sample_infos, regionin, regionout,ref, index, map] [meta, fasta, fai] input[0] = input_bam .combine(ref_panel) .combine(map_file) - input[1] = Channel.of([[],[],[]]) + input[1] = channel.of([[],[],[]]) """ } } @@ -87,7 +93,12 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - path(process.out.phased_variants[0][1]).vcf.variantsMD5, + process.out.phased_variants.collect{ meta, vcf -> [ + meta, + file(vcf).name, + path(vcf).vcf.summary, + path(vcf).vcf.variantsMD5 + ]}, process.out.stats_coverage, process.out.versions ).match()} @@ -102,14 +113,14 @@ nextflow_process { script "../../../samtools/view" process { """ - input[0] = Channel.of([ + input[0] = channel.of([ [id:'input'], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam.bai", checkIfExists: true) + 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([ + input[1] = channel.of([ [id: 'Hg38'], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/GRCh37_chr22.fasta.gz", checkIfExists: true) + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genomeGRCh38_chr21_22.fa.gz", checkIfExists: true) ]) input[2] = [] input[3] = "crai" @@ -123,22 +134,22 @@ nextflow_process { """ input_cram = SAMTOOLS_VIEW.out.cram .join(SAMTOOLS_VIEW.out.crai) - .combine(Channel.of([ + .combine(channel.of([ [], [], "chr22:16600000-16800000", "chr22:16650000-16750000", ])) - ref_panel = Channel.of([ + ref_panel = 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) ]) - map_file = Channel.of([[]]) + map_file = channel.of([[]]) - reference_genome = Channel.of([ + reference_genome = channel.of([ [id: 'Hg38'], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/GRCh37_chr22.fasta.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.fasta.fai", checkIfExists: true) + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genomeGRCh38_chr21_22.fa.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genomeGRCh38_chr21_22.fa.gz.fai", checkIfExists: true) ]) // [meta, vcf, index, sample_infos, regionin, regionout,ref, index, map] [meta, fasta, fai] @@ -154,7 +165,12 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - path(process.out.phased_variants[0][1]).vcf.variantsMD5, + process.out.phased_variants.collect{ meta, vcf -> [ + meta, + file(vcf).name, + path(vcf).vcf.summary, + path(vcf).vcf.variantsMD5 + ]}, process.out.stats_coverage, process.out.versions ).match()} @@ -163,35 +179,36 @@ nextflow_process { } test("homo_sapiens - [bam, bam] region - panel") { + tag "test" when { process { """ - input_bam = Channel.of([ + input_bam = channel.of([ [id:'input'], [ - file("https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/individuals/NA12878/NA12878.s.bam", checkIfExists: true), - file("https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/individuals/NA19401/NA19401.s.bam", checkIfExists: true) + 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/NA19401.chr21_22.1X.bam", checkIfExists: true) ], [ - file("https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/individuals/NA12878/NA12878.s.bam.bai", checkIfExists: true), - file("https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/individuals/NA19401/NA19401.s.bam.bai", 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/illumina/bam/NA19401.chr21_22.1X.bam.bai", checkIfExists: true) ], [], [], "chr22:16600000-16800000", "chr22:16650000-16750000", ]) - ref_panel = Channel.of([ + ref_panel = 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) ]) - map_file = Channel.of([[]]) + map_file = channel.of([[]]) // [meta, vcf, index, sample_infos, regionin, regionout,ref, index, map] [meta, fasta, fai] input[0] = input_bam .combine(ref_panel) .combine(map_file) - input[1] = Channel.of([[],[],[]]) + input[1] = channel.of([[],[],[]]) """ } } @@ -200,8 +217,12 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - // path(process.out.phased_variants[0][1]).vcf.variantsMD5, // MD5 sum not stable for the AF infos of 1 variant at the 5th decimals - process.out.phased_variants.collect{ path(it[1]).vcf.summary.replaceAll(", phasedAutodetect=(false|true)", "") }, + process.out.phased_variants.collect{ meta, vcf -> [ + meta, + file(vcf).name, + path(vcf).vcf.summary, + path(vcf).vcf.variantsMD5 + ]}, process.out.stats_coverage, process.out.versions ).match()} @@ -213,15 +234,15 @@ nextflow_process { when { process { """ - input_bam = Channel.of([ + input_bam = channel.of([ [id:'input'], [ - file("https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/individuals/NA12878/NA12878.s.bam", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true) + 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/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz", checkIfExists: true) ], [ - file("https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/individuals/NA12878/NA12878.s.bam.bai", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", 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/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExists: true) ], [], [], "chr22:16600000-16800000", @@ -231,7 +252,7 @@ nextflow_process { // [meta, vcf, index, sample_infos, regionin, regionout,ref, index, map] [meta, fasta, fai] input[0] = input_bam - input[1] = Channel.of([[],[],[]]) + input[1] = channel.of([[],[],[]]) """ } } @@ -248,15 +269,15 @@ nextflow_process { when { process { """ - input_bam = Channel.of([ + input_bam = channel.of([ [id:'input'], [ - file("https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/individuals/NA12878/NA12878.s.1x.bcf", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA19401.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", checkIfExists: true), ], [ - file("https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/individuals/NA12878/NA12878.s.1x.bcf.csi", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA19401.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExists: true), ], [], [], "chr21:16600000-16800000", @@ -266,7 +287,7 @@ nextflow_process { // [meta, vcf, index, sample_infos, regionin, regionout,ref, index, map] [meta, fasta, fai] input[0] = input_bam - input[1] = Channel.of([[],[],[]]) + input[1] = channel.of([[],[],[]]) """ } } @@ -280,23 +301,24 @@ nextflow_process { } test("homo_sapiens - [bam, bam] region sample rename - panel") { + tag "test" when { process { """ - bamlist = Channel.of( - "NA12878.s.bam\tNA12878", - "NA19401.s.bam\tNA19401" + bamlist = channel.of( + "NA12878.chr21_22.1X.bam\tSample1", + "NA19401.chr21_22.1X.bam\tSample2" ).collectFile(name: 'bamlist.txt', newLine: true) - input_bam = Channel.of([ + input_bam = channel.of([ [id:'input'], [ - file("https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/individuals/NA12878/NA12878.s.bam", checkIfExists: true), - file("https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/individuals/NA19401/NA19401.s.bam", checkIfExists: true) + 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/NA19401.chr21_22.1X.bam", checkIfExists: true) ], [ - file("https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/individuals/NA12878/NA12878.s.bam.bai", checkIfExists: true), - file("https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/individuals/NA19401/NA19401.s.bam.bai", 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/illumina/bam/NA19401.chr21_22.1X.bam.bai", checkIfExists: true) ], ]).combine(bamlist) .map{ map, bam, bai, bamlist -> [ @@ -305,17 +327,17 @@ nextflow_process { "chr22:16650000-16750000", ]} - ref_panel = Channel.of([ + ref_panel = 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) ]) - map_file = Channel.of([[]]) + map_file = channel.of([[]]) // [meta, vcf, index, sample_infos, regionin, regionout,ref, index, map] [meta, fasta, fai] input[0] = input_bam .combine(ref_panel) .combine(map_file) - input[1] = Channel.of([[],[],[]]) + input[1] = channel.of([[],[],[]]) """ } } @@ -324,8 +346,14 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - process.out.phased_variants.collect{ path(it[1]).vcf.header.getGenotypeSamples().sort() }, - process.out.phased_variants.collect{ path(it[1]).vcf.summary.replaceAll(", phasedAutodetect=(false|true)", "") } + process.out.phased_variants.collect{ meta, vcf -> [ + meta, + file(vcf).name, + path(vcf).vcf.summary, + path(vcf).vcf.variantsMD5 + ]}, + process.out.stats_coverage, + process.out.versions ).match()} ) } @@ -336,10 +364,10 @@ nextflow_process { when { process { """ - input_vcf = Channel.of([ + input_vcf = channel.of([ [ id:'input' ], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + 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), [], [], "chr22:16600000-16800000", "chr22:16650000-16750000", @@ -348,7 +376,7 @@ nextflow_process { // [meta, vcf, index, sample_infos, regionin, regionout,ref, index, map] [meta, fasta, fai] input[0] = input_vcf - input[1] = Channel.of([[],[],[]]) + input[1] = channel.of([[],[],[]]) """ } } @@ -356,10 +384,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot( - process.out, - path(process.out.versions[0]).yaml - ).match()} + { assert snapshot(process.out).match()} ) } diff --git a/modules/nf-core/glimpse2/phase/tests/main.nf.test.snap b/modules/nf-core/glimpse2/phase/tests/main.nf.test.snap index 52fe9b37acca..143504524b83 100644 --- a/modules/nf-core/glimpse2/phase/tests/main.nf.test.snap +++ b/modules/nf-core/glimpse2/phase/tests/main.nf.test.snap @@ -1,13 +1,22 @@ { "homo_sapiens - bam region - panel": { "content": [ - "b84087788284d7ca02e23a0a24da2cff", [ [ { "id": "input" }, - "input_chr22_16650000-16750000_stats_coverage.txt.gz:md5,5682c97193f6cd8041f3bc4ef81e7252" + "input_chr22_16650000-16750000.vcf", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=266, phased=true, phasedAutodetect=false]", + "23026b2111d5b93194ebbb5de09d654d" + ] + ], + [ + [ + { + "id": "input" + }, + "input_chr22_16650000-16750000_stats_coverage.txt.gz:md5,39bf5e7c67e377207656104f64fea657" ] ], [ @@ -15,22 +24,29 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-19T22:59:18.246884827" + "timestamp": "2025-11-26T20:59:49.43898101" }, "homo_sapiens - [bam, bam] region - panel": { "content": [ [ - "VcfFile [chromosomes=[chr22], sampleCount=2, variantCount=266, phased=true]" + [ + { + "id": "input" + }, + "input_chr22_16650000-16750000.vcf", + "VcfFile [chromosomes=[chr22], sampleCount=2, variantCount=266, phased=true, phasedAutodetect=false]", + "f06d12e3c16a8edc313ad564836008" + ] ], [ [ { "id": "input" }, - "input_chr22_16650000-16750000_stats_coverage.txt.gz:md5,ce67a9fd6944b74e65ab6f401b1b9bb0" + "input_chr22_16650000-16750000_stats_coverage.txt.gz:md5,fa1b295b071c1b8670c013577a982139" ] ], [ @@ -38,27 +54,48 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-19T23:09:13.67984812" + "timestamp": "2025-11-26T21:03:14.8627618" }, "homo_sapiens - vcf region - panel": { "content": [ - "d8e9e1ec4d9d229536a23f2f69a469de", + [ + [ + { + "id": "input" + }, + "input_chr22_16650000-16750000.vcf", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=266, phased=true, phasedAutodetect=false]", + "d8e9e1ec4d9d229536a23f2f69a469de" + ] + ], + [ + + ], [ "versions.yml:md5,c68de03046a6503cdbcf3a1495fc512f" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-19T22:59:11.310995509" + "timestamp": "2025-11-26T20:58:13.192800596" }, "homo_sapiens - cram region - panel - fasta": { "content": [ - "d8e9e1ec4d9d229536a23f2f69a469de", + [ + [ + { + "id": "input" + }, + "input_chr22_16650000-16750000.vcf", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=266, phased=true, phasedAutodetect=false]", + "d8e9e1ec4d9d229536a23f2f69a469de" + ] + ], [ [ { @@ -72,28 +109,40 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-19T22:59:28.11190592" + "timestamp": "2025-11-26T21:00:40.288219943" }, "homo_sapiens - [bam, bam] region sample rename - panel": { "content": [ [ [ - "NA12878", - "NA19401" + { + "id": "input" + }, + "input_chr22_16650000-16750000.vcf", + "VcfFile [chromosomes=[chr22], sampleCount=2, variantCount=266, phased=true, phasedAutodetect=false]", + "f2aff70c52df2f69d9bc1f4bf63fcb5c" + ] + ], + [ + [ + { + "id": "input" + }, + "input_chr22_16650000-16750000_stats_coverage.txt.gz:md5,b21fbf77322b281c5cf4822edadd844c" ] ], [ - "VcfFile [chromosomes=[chr22], sampleCount=2, variantCount=266, phased=true]" + "versions.yml:md5,c68de03046a6503cdbcf3a1495fc512f" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-19T22:59:55.383590515" + "timestamp": "2025-11-26T21:05:13.564441099" }, "homo_sapiens - vcf region - panel -- stub": { "content": [ @@ -126,17 +175,12 @@ "versions": [ "versions.yml:md5,c68de03046a6503cdbcf3a1495fc512f" ] - }, - { - "GLIMPSE2_PHASE": { - "glimpse2": "2.0.0" - } } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-05-19T23:19:50.900935094" + "timestamp": "2025-11-26T21:01:07.257765596" } } \ No newline at end of file diff --git a/modules/nf-core/glimpse2/phase/tests/nextflow.config b/modules/nf-core/glimpse2/phase/tests/nextflow.config index 820e20151921..310c7f220dd7 100644 --- a/modules/nf-core/glimpse2/phase/tests/nextflow.config +++ b/modules/nf-core/glimpse2/phase/tests/nextflow.config @@ -1,5 +1,6 @@ process { withName: GLIMPSE2_PHASE { + cpus = 1 ext.args = "--seed 1" ext.suffix = "vcf" } diff --git a/modules/nf-core/glimpse2/splitreference/tests/main.nf.test b/modules/nf-core/glimpse2/splitreference/tests/main.nf.test index d10648c40e1e..e95febde9a3c 100644 --- a/modules/nf-core/glimpse2/splitreference/tests/main.nf.test +++ b/modules/nf-core/glimpse2/splitreference/tests/main.nf.test @@ -52,7 +52,7 @@ nextflow_process { ] input[1]= [ [ id:'map'], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.GRCh38.glimpse.chr22.map.gz", checkIfExists:true) + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.glimpse.map", checkIfExists:true) ] """ } diff --git a/subworkflows/nf-core/multiple_impute_glimpse2/main.nf b/subworkflows/nf-core/multiple_impute_glimpse2/main.nf index 47fb600f3c23..c9c0022beacc 100644 --- a/subworkflows/nf-core/multiple_impute_glimpse2/main.nf +++ b/subworkflows/nf-core/multiple_impute_glimpse2/main.nf @@ -10,13 +10,13 @@ workflow MULTIPLE_IMPUTE_GLIMPSE2 { take: ch_input // channel (mandatory): [ meta, vcf, csi, infos ] ch_ref // channel (mandatory): [ meta, vcf, csi, region ] - ch_map // channel (optional): [ meta, map ] - ch_fasta // channel (optional): [ meta, fasta, index ] + ch_map // channel (optional) : [ meta, map ] + ch_fasta // channel (optional) : [ meta, fasta, index ] chunk_model // string: model used to chunk the reference panel main: - ch_versions = Channel.empty() + ch_versions = channel.empty() // Chunk reference panel ch_ref_map = ch_ref.combine(ch_map, by: 0) @@ -48,10 +48,10 @@ workflow MULTIPLE_IMPUTE_GLIMPSE2 { // Phase input files for each reference bin files + indexing GLIMPSE2_PHASE ( phase_input, ch_fasta ) // [meta, vcf, index, sample_infos, regionin, regionout, regionindex, ref, ref_index, map], [ meta, fasta, index ] - ch_versions = ch_versions.mix( GLIMPSE2_PHASE.out.versions) + ch_versions = ch_versions.mix( GLIMPSE2_PHASE.out.versions.first() ) INDEX_PHASE ( GLIMPSE2_PHASE.out.phased_variants ) - ch_versions = ch_versions.mix( INDEX_PHASE.out.versions ) + ch_versions = ch_versions.mix( INDEX_PHASE.out.versions.first() ) // Ligate all phased files in one and index it ligate_input = GLIMPSE2_PHASE.out.phased_variants @@ -61,10 +61,10 @@ workflow MULTIPLE_IMPUTE_GLIMPSE2 { .collect(), by: 0 ) GLIMPSE2_LIGATE ( ligate_input ) - ch_versions = ch_versions.mix( GLIMPSE2_LIGATE.out.versions ) + ch_versions = ch_versions.mix( GLIMPSE2_LIGATE.out.versions.first() ) INDEX_LIGATE ( GLIMPSE2_LIGATE.out.merged_variants ) - ch_versions = ch_versions.mix( INDEX_LIGATE.out.versions ) + ch_versions = ch_versions.mix( INDEX_LIGATE.out.versions.first() ) emit: chunk_chr = GLIMPSE2_CHUNK.out.chunk_chr // channel: [ val(meta), txt ] diff --git a/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test b/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test index 43f17ec771d7..989bdb8a1ca7 100644 --- a/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test +++ b/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test @@ -24,8 +24,8 @@ nextflow_workflow { """ input[0] = Channel.of([ [id:'input_vcf'], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + 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] = Channel.of([ @@ -63,8 +63,8 @@ nextflow_workflow { .collectFile(name: 'sampleinfos.txt') input[0] = Channel.of([ [id:'input_vcf'], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + 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), ]).combine(sample) input[1] = Channel.of([ [id:'ref_panel', chr: "22"], @@ -103,8 +103,8 @@ nextflow_workflow { """ input[0] = Channel.of([ [id:'input_bam'], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam.bai", checkIfExists: true), + 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([ @@ -142,8 +142,8 @@ nextflow_workflow { """ input[0] = input[0] = Channel.of([ [id:'input_bam'], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam.bai", checkIfExists: true), + 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([ diff --git a/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test.snap b/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test.snap index c75e08a02aee..232c67643f96 100644 --- a/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test.snap +++ b/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test.snap @@ -17,19 +17,17 @@ [ "versions.yml:md5,048d5415737cdc568fcc4fbdc5df11e2", "versions.yml:md5,1301ab7e8d92b232e306aef24d94e252", - "versions.yml:md5,1301ab7e8d92b232e306aef24d94e252", "versions.yml:md5,1362d3f6834c21239d705f550b11c2af", "versions.yml:md5,2373902d5432eba6898c90d4c4685f90", "versions.yml:md5,642ed64b13825472557113ba2e4b1566", - "versions.yml:md5,e81cfbe9cf12832b8312f966b6c9beb1", "versions.yml:md5,e81cfbe9cf12832b8312f966b6c9beb1" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-15T07:30:09.139160775" + "timestamp": "2025-11-27T11:11:34.893641629" }, "homo_sapiens - bam [] - panel vcf - [] - [] - sequential": { "content": [ @@ -43,7 +41,7 @@ ] ], [ - "11558863c409ca2d6278e699cd5fde1a" + "49df7da6c9745ba9a86112193ff172a9" ], "input_bam.vcf.gz.csi", [ @@ -56,10 +54,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-15T07:30:25.249656096" + "timestamp": "2025-11-26T21:19:09.9592341" }, "homo_sapiens - bam [] - panel vcf - [] - [] - sequential -- stub": { "content": [ diff --git a/subworkflows/nf-core/vcf_impute_glimpse/main.nf b/subworkflows/nf-core/vcf_impute_glimpse/main.nf index 94262e34ae14..9b6884df3e1c 100644 --- a/subworkflows/nf-core/vcf_impute_glimpse/main.nf +++ b/subworkflows/nf-core/vcf_impute_glimpse/main.nf @@ -11,30 +11,30 @@ workflow VCF_IMPUTE_GLIMPSE { main: - ch_versions = Channel.empty() + ch_versions = channel.empty() input_chunk = ch_input.map{ - meta, vcf, csi, sample, region, ref, ref_index, map -> + meta, vcf, csi, _sample, region, _ref, _ref_index, _map -> [ meta, vcf, csi, region] } GLIMPSE_CHUNK ( input_chunk ) - ch_versions = ch_versions.mix( GLIMPSE_CHUNK.out.versions ) + ch_versions = ch_versions.mix( GLIMPSE_CHUNK.out.versions.first() ) chunk_output = GLIMPSE_CHUNK.out.chunk_chr .splitCsv(header: ['ID', 'Chr', 'RegionIn', 'RegionOut', 'Size1', 'Size2'], sep: "\t", skip: 0) .map { meta, it -> [meta, it["RegionIn"], it["RegionOut"]]} - phase_input = ch_input.map{ meta, vcf, csi, sample, region, ref, ref_index, map -> [meta, vcf, csi, sample, ref, ref_index, map]} + phase_input = ch_input.map{ meta, vcf, csi, sample, _region, ref, ref_index, map -> [meta, vcf, csi, sample, ref, ref_index, map]} .combine(chunk_output, by: 0) .map{meta, vcf, csi, sample, ref, ref_index, map, regionin, regionout -> [meta, vcf, csi, sample, regionin, regionout, ref, ref_index, map]} GLIMPSE_PHASE ( phase_input ) // [meta, vcf, index, sample_infos, regionin, regionout, ref, ref_index, map] - ch_versions = ch_versions.mix(GLIMPSE_PHASE.out.versions ) + ch_versions = ch_versions.mix(GLIMPSE_PHASE.out.versions.first() ) INDEX_PHASE ( GLIMPSE_PHASE.out.phased_variants ) - ch_versions = ch_versions.mix( INDEX_PHASE.out.versions ) + ch_versions = ch_versions.mix( INDEX_PHASE.out.versions.first() ) // Ligate all phased files in one and index it ligate_input = GLIMPSE_PHASE.out.phased_variants @@ -45,10 +45,10 @@ workflow VCF_IMPUTE_GLIMPSE { ) GLIMPSE_LIGATE ( ligate_input ) - ch_versions = ch_versions.mix(GLIMPSE_LIGATE.out.versions ) + ch_versions = ch_versions.mix(GLIMPSE_LIGATE.out.versions.first() ) INDEX_LIGATE ( GLIMPSE_LIGATE.out.merged_variants ) - ch_versions = ch_versions.mix( INDEX_LIGATE.out.versions ) + ch_versions = ch_versions.mix( INDEX_LIGATE.out.versions.first() ) emit: chunk_chr = GLIMPSE_CHUNK.out.chunk_chr // channel: [ val(meta), txt ] diff --git a/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test b/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test index 29b71c982273..a7dfec8a7ccc 100644 --- a/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test +++ b/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test @@ -18,7 +18,6 @@ nextflow_workflow { when { params { outdir = "tests/results" - impute_dataset = "https://raw.githubusercontent.com/nf-core/test-datasets/phaseimpute/hum_data/" } workflow { """ @@ -26,11 +25,11 @@ nextflow_workflow { ch_panel = Channel.fromList([ [[ chr:"chr21"], - file(params.impute_dataset + "panel/chr21/1000GP.chr21.s.norel.vcf.gz", checkIfExists: true), - file(params.impute_dataset + "panel/chr21/1000GP.chr21.s.norel.vcf.gz.csi", checkIfExists: true)], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz", checkIfExists:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz.csi", checkIfExists:true)], [[ chr:"chr22"], - file(params.impute_dataset + "panel/chr22/1000GP.chr22.s.norel.vcf.gz", checkIfExists: true), - file(params.impute_dataset + "panel/chr22/1000GP.chr22.s.norel.vcf.gz.csi", 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)] ]) region = Channel.fromList([ [[chr: "chr21", region: "chr21:16600000-16800000"], "chr21:16600000-16800000"], @@ -39,12 +38,12 @@ nextflow_workflow { input_vcf = Channel.fromList([ [[ id:'NA12878'], // meta map - file(params.impute_dataset + "individuals/NA12878/NA12878.s.1x.bcf", checkIfExists: true), - file(params.impute_dataset + "individuals/NA12878/NA12878.s.1x.bcf.csi", checkIfExists: true), + 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), ], [[ id:'NA19401'], // meta map - file(params.impute_dataset + "individuals/NA19401/NA19401.s.1x.bcf", checkIfExists: true), - file(params.impute_dataset + "individuals/NA19401/NA19401.s.1x.bcf.csi", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA19401.chr21_22.1X.glimpse2.vcf.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA19401.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExists: true), ] ]) input_vcf_multiple = input_vcf @@ -56,10 +55,10 @@ nextflow_workflow { ch_map = Channel.fromList([ [[ chr: "chr21"], - file(params.impute_dataset + "reference_genome/GRCh38_chr21.glimpse.map", checkIfExists: true) + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr21.glimpse.map", checkIfExists: true) ], [[ chr: "chr22"], - file(params.impute_dataset + "reference_genome/GRCh38_chr21.glimpse.map", checkIfExists: true) + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.glimpse.map", checkIfExists: true) ] ]) @@ -78,13 +77,18 @@ nextflow_workflow { } then { - def lines = path(workflow.out.merged_variants.get(0).get(1)).linesGzip.last() assertAll( { assert workflow.success }, - { assert snapshot(workflow.out.versions).match("versions") }, - { assert snapshot(workflow.out.chunk_chr).match("chunk_chr") }, - { assert workflow.out.merged_variants.size() == 4}, - { assert snapshot(lines).match("merged") } + { assert snapshot( + workflow.out.versions, + workflow.out.chunk_chr, + workflow.out.merged_variants.collect{ meta, vcf -> [ + meta, + file(vcf).name, + path(vcf).vcf.summary, + path(vcf).vcf.variantsMD5 + ]} + ).match() } ) } diff --git a/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test.snap b/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test.snap index e1e48f2e30f6..d0174f8cacc8 100644 --- a/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test.snap +++ b/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test.snap @@ -1,6 +1,13 @@ { - "chunk_chr": { + "Should run without failures": { "content": [ + [ + "versions.yml:md5,21a662d09502bd6516ec62b72e4fb182", + "versions.yml:md5,227d8e960e4382d8a615e040b874fc27", + "versions.yml:md5,4c01309242fd8da3ddbde9fab54aae4c", + "versions.yml:md5,7ae4d2b0252f9382dd08d783b7a234d2", + "versions.yml:md5,c7bdac5a09390d02a95e5042a2fd133e" + ], [ [ { @@ -16,7 +23,7 @@ "chr": "chr22", "region": "chr22:16600000-16800000" }, - "NA12878_chr22:16600000-16800000_chunk.txt:md5,f5270ed0faa4f9697618444b267442ce" + "NA12878_chr22:16600000-16800000_chunk.txt:md5,7ac5d116bc3357a154946576c21060cd" ], [ { @@ -32,55 +39,56 @@ "chr": "chr22", "region": "chr22:16600000-16800000" }, - "NA19401_chr22:16600000-16800000_chunk.txt:md5,f5270ed0faa4f9697618444b267442ce" + "NA19401_chr22:16600000-16800000_chunk.txt:md5,7ac5d116bc3357a154946576c21060cd" ] - ] - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" - }, - "timestamp": "2025-03-01T13:00:44.904715825" - }, - "versions": { - "content": [ + ], [ - "versions.yml:md5,227d8e960e4382d8a615e040b874fc27", - "versions.yml:md5,227d8e960e4382d8a615e040b874fc27", - "versions.yml:md5,227d8e960e4382d8a615e040b874fc27", - "versions.yml:md5,227d8e960e4382d8a615e040b874fc27", - "versions.yml:md5,4c01309242fd8da3ddbde9fab54aae4c", - "versions.yml:md5,4c01309242fd8da3ddbde9fab54aae4c", - "versions.yml:md5,4c01309242fd8da3ddbde9fab54aae4c", - "versions.yml:md5,4c01309242fd8da3ddbde9fab54aae4c", - "versions.yml:md5,73621eae1bfd89c2ceb009524fe680d4", - "versions.yml:md5,73621eae1bfd89c2ceb009524fe680d4", - "versions.yml:md5,73621eae1bfd89c2ceb009524fe680d4", - "versions.yml:md5,73621eae1bfd89c2ceb009524fe680d4", - "versions.yml:md5,7ae4d2b0252f9382dd08d783b7a234d2", - "versions.yml:md5,7ae4d2b0252f9382dd08d783b7a234d2", - "versions.yml:md5,7ae4d2b0252f9382dd08d783b7a234d2", - "versions.yml:md5,7ae4d2b0252f9382dd08d783b7a234d2", - "versions.yml:md5,c7bdac5a09390d02a95e5042a2fd133e", - "versions.yml:md5,c7bdac5a09390d02a95e5042a2fd133e", - "versions.yml:md5,c7bdac5a09390d02a95e5042a2fd133e", - "versions.yml:md5,c7bdac5a09390d02a95e5042a2fd133e" + [ + { + "id": "NA12878", + "chr": "chr21", + "region": "chr21:16600000-16800000" + }, + "NA12878_chr21_null_ligate.vcf.gz", + "VcfFile [chromosomes=[chr21], sampleCount=1, variantCount=211, phased=false, phasedAutodetect=false]", + "66d0bfb31b037fb57d6b56e65b7cd6a7" + ], + [ + { + "id": "NA12878", + "chr": "chr22", + "region": "chr22:16600000-16800000" + }, + "NA12878_chr22_null_ligate.vcf.gz", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=266, phased=false, phasedAutodetect=false]", + "58751684e0168ad0485ba3510e0cfd3e" + ], + [ + { + "id": "NA19401", + "chr": "chr21", + "region": "chr21:16600000-16800000" + }, + "NA19401_chr21_null_ligate.vcf.gz", + "VcfFile [chromosomes=[chr21], sampleCount=1, variantCount=211, phased=false, phasedAutodetect=false]", + "66d0bfb31b037fb57d6b56e65b7cd6a7" + ], + [ + { + "id": "NA19401", + "chr": "chr22", + "region": "chr22:16600000-16800000" + }, + "NA19401_chr22_null_ligate.vcf.gz", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=266, phased=false, phasedAutodetect=false]", + "58751684e0168ad0485ba3510e0cfd3e" + ] ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" - }, - "timestamp": "2025-09-15T09:04:33.581167" - }, - "merged": { - "content": [ - "chr21\t16609998\tchr21:16609998:A:G\tA\tG\t.\t.\tRAF=0.00125156;AF=0;INFO=1\tGT:DS:GP:HS\t0/0:0:1,0,0:0" - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-03-01T13:00:44.91963315" + "timestamp": "2025-11-27T11:10:39.309436558" } } \ No newline at end of file From 819155d882dd219b2d2a4e83c1afbb8852a827a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Thu, 4 Dec 2025 16:51:06 +0100 Subject: [PATCH 15/83] meta.yml schema: add `containers` section, fix order and simplify (#9503) * fix order * add container section * simplify schema * require https for singluarity --- modules/meta-schema.json | 299 ++++++++++++++++++++++----------------- 1 file changed, 167 insertions(+), 132 deletions(-) diff --git a/modules/meta-schema.json b/modules/meta-schema.json index b5d28ce094fa..10956c410ee4 100644 --- a/modules/meta-schema.json +++ b/modules/meta-schema.json @@ -24,124 +24,6 @@ "uniqueItems": true, "minItems": 3 }, - "authors": { - "type": "array", - "description": "Authors of the module", - "items": { - "type": "string" - } - }, - "maintainers": { - "type": "array", - "description": "Maintainers of the module", - "items": { - "type": "string" - } - }, - "extra_args": { - "type": "array", - "description": "Extra arguments for the module", - "items": { - "type": "object", - "properties": { - "description": { - "type": "string", - "description": "Description of the argument" - } - } - } - }, - "input": { - "type": "array", - "description": "Input channels for the module", - "items": { - "oneOf": [ - { - "type": "array", - "items": { - "type": "object", - "patternProperties": { - ".*": { - "$ref": "#/definitions/elementProperties" - } - } - } - }, - { - "type": "object", - "patternProperties": { - ".*": { - "$ref": "#/definitions/elementProperties" - } - } - } - ] - } - }, - "output": { - "type": "object", - "description": "Output channels for the module", - "patternProperties": { - ".*": { - "type": "array", - "items": { - "oneOf": [ - { - "type": "object", - "patternProperties": { - ".*": { - "$ref": "#/definitions/elementProperties" - } - } - }, - { - "type": "array", - "items": { - "type": "object", - "patternProperties": { - ".*": { - "$ref": "#/definitions/elementProperties" - } - } - } - } - ] - } - } - } - }, - "topics": { - "type": "object", - "description": "Topics of the module", - "patternProperties": { - ".*": { - "type": "array", - "items": { - "oneOf": [ - { - "type": "object", - "patternProperties": { - ".*": { - "$ref": "#/definitions/elementProperties" - } - } - }, - { - "type": "array", - "items": { - "type": "object", - "patternProperties": { - ".*": { - "$ref": "#/definitions/elementProperties" - } - } - } - } - ] - } - } - } - }, "tools": { "type": "array", "description": "Tools used by the module", @@ -158,17 +40,17 @@ "homepage": { "type": "string", "description": "Homepage of the tool", - "pattern": "^(http|https)://.*$" + "pattern": "^https?://.*$" }, "documentation": { "type": "string", "description": "Documentation of the tool", - "pattern": "^(http|https|ftp)://.*$" + "pattern": "^(https?|ftp)://.*$" }, "tool_dev_url": { "type": "string", "description": "URL of the development version of the tool's documentation", - "pattern": "^(http|https)://.*$" + "pattern": "^https?://.*$" }, "doi": { "description": "DOI of the tool", @@ -194,17 +76,9 @@ "message": "Licence must be an array of one or more entries, e.g. [\"MIT\"]" }, "identifier": { + "type": "string", "description": "bio.tools identifier of the tool", - "anyOf": [ - { - "type": "string", - "pattern": "^biotools:.*$" - }, - { - "type": "string", - "maxLength": 0 - } - ] + "pattern": "^(biotools:.*)?$" } }, "required": ["description"], @@ -225,9 +99,134 @@ } } } + }, + "extra_args": { + "type": "array", + "description": "Extra arguments for the module", + "items": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "Description of the argument" + } + } + } + }, + "input": { + "type": "array", + "description": "Input channels for the module", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/channelElement" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/channelElement" + } + } + ] + } + }, + "output": { + "type": "object", + "description": "Output channels for the module", + "patternProperties": { + ".*": { + "$ref": "#/definitions/channelArray" + } + } + }, + "topics": { + "type": "object", + "description": "Topics of the module", + "patternProperties": { + ".*": { + "$ref": "#/definitions/channelArray" + } + } + }, + "authors": { + "type": "array", + "description": "Authors of the module", + "items": { + "type": "string" + } + }, + "maintainers": { + "type": "array", + "description": "Maintainers of the module", + "items": { + "type": "string" + } + }, + "containers": { + "type": "object", + "description": "Container images for the module", + "properties": { + "docker": { + "type": "object", + "description": "Docker containers for different architectures", + "additionalProperties": { + "$ref": "#/definitions/container" + } + }, + "singularity": { + "type": "object", + "description": "Singularity containers for different architectures", + "additionalProperties": { + "allOf": [ + { + "$ref": "#/definitions/container" + }, + { + "properties": { + "name": { + "pattern": "^oras://.*$" + } + }, + "required": ["https"] + } + ] + } + }, + "conda": { + "type": "object", + "description": "Conda lock files for different architectures", + "additionalProperties": { + "$ref": "#/definitions/condaLockFile" + } + } + } } }, "definitions": { + "channelElement": { + "type": "object", + "patternProperties": { + ".*": { + "$ref": "#/definitions/elementProperties" + } + } + }, + "channelArray": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/channelElement" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/channelElement" + } + } + ] + } + }, "elementProperties": { "type": "object", "properties": { @@ -261,13 +260,49 @@ "patternProperties": { ".*": { "type": "string", - "pattern": "^(http|https)://.*" + "pattern": "^https?://.*" } } } } }, "required": ["type", "description"] + }, + "container": { + "type": "object", + "description": "Container information for Docker or Singularity", + "properties": { + "name": { + "type": "string", + "description": "Container name/URI" + }, + "https": { + "type": "string", + "description": "HTTPS URL to download the container (only for Singularity)", + "pattern": "^https://.*$" + }, + "build_id": { + "type": "string", + "description": "Build ID of the container" + }, + "scan_id": { + "type": "string", + "description": "Security scan ID of the container (only for Docker)" + } + }, + "required": ["name", "build_id"] + }, + "condaLockFile": { + "type": "object", + "description": "Conda lock file information", + "properties": { + "lock file": { + "type": "string", + "description": "URL to the conda lock file", + "pattern": "^https://.*$" + } + }, + "required": ["lock file"] } }, "required": ["name", "description", "keywords", "authors", "output", "tools"] From 53675cff537974a67cc108648e82a1f22d582aab Mon Sep 17 00:00:00 2001 From: Maxime U Garcia Date: Fri, 5 Dec 2025 10:32:19 +0100 Subject: [PATCH 16/83] update and add topics to snakemake module (#9454) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update and add topics * add new topics structure * add stub test and capture version in snapshot * update to 9.14.0 * fix singularity be setting cache_dir * fix stub --------- Co-authored-by: Matthias Hörtenhuber Co-authored-by: mashehu --- modules/nf-core/snakemake/environment.yml | 2 +- modules/nf-core/snakemake/main.nf | 51 ++++++++---------- modules/nf-core/snakemake/meta.yml | 37 ++++++++----- modules/nf-core/snakemake/tests/main.nf.test | 53 +++++++++++++++++-- .../nf-core/snakemake/tests/main.nf.test.snap | 39 ++++++++++++-- 5 files changed, 133 insertions(+), 49 deletions(-) diff --git a/modules/nf-core/snakemake/environment.yml b/modules/nf-core/snakemake/environment.yml index 39223df49ef0..66b1e8576593 100644 --- a/modules/nf-core/snakemake/environment.yml +++ b/modules/nf-core/snakemake/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::snakemake=7.31.0 + - bioconda::snakemake=9.14.0 diff --git a/modules/nf-core/snakemake/main.nf b/modules/nf-core/snakemake/main.nf index d5cccdef9657..1b3acf6c5f8b 100644 --- a/modules/nf-core/snakemake/main.nf +++ b/modules/nf-core/snakemake/main.nf @@ -1,56 +1,51 @@ process SNAKEMAKE { - tag "$meta.id" + tag "${meta.id}" label 'process_low' // You will have to add all modules to this Conda definition and // replace the container definition for one that suits your needs conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/snakemake:7.31.0--hdfd78af_1' : - 'biocontainers/snakemake:7.31.0--hdfd78af_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/b9/b91b2eddb4c4c0a5e17721d29764e59a50035b9fa9996eb9cb392829f2d7a533/data' + : 'community.wave.seqera.io/library/snakemake:9.14.0--dfee75b6201d25c6'}" input: tuple val(meta), path(inputs) tuple val(meta2), path(snakefile) output: - tuple val(meta), path("[!.snakemake|versions.yml]**") , emit: outputs , optional: true + tuple val(meta), path("[!.snakemake|versions.yml]**"), emit: outputs, optional: true tuple val(meta), path(".snakemake", type: 'dir', hidden: true), emit: snakemake_dir - path "versions.yml" , emit: versions + tuple val("${task.process}"), val("snakemake"), eval('snakemake --version'), topic: versions, emit: versions_snakemake when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def cores = task.cpus ? "--cores ${task.cpus}" : "--cores all" + def args = task.ext.args ?: '' + def cores = task.cpus ? "--cores ${task.cpus}" : "--cores all" """ + export XDG_CACHE_HOME=\$PWD/snakemake_cache + mkdir -p \$XDG_CACHE_HOME + snakemake \\ - $args \\ - $cores \\ - --snakefile $snakefile - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - snakemake: \$(snakemake --version) - END_VERSIONS + ${args} \\ + ${cores} \\ + --snakefile ${snakefile} """ + stub: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def cores = task.cpus ? "--cores ${task.cpus}" : "--cores all" + def args = task.ext.args ?: '' + def cores = task.cpus ? "--cores ${task.cpus}" : "--cores all" """ + export XDG_CACHE_HOME=\$PWD/snakemake_cache + mkdir -p \$XDG_CACHE_HOME + snakemake \\ - $args \\ - --snakefile $snakefile \\ - $cores \\ + ${args} \\ + --snakefile ${snakefile} \\ + ${cores} \\ --dry-run - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - snakemake: \$(snakemake --version) - END_VERSIONS """ } diff --git a/modules/nf-core/snakemake/meta.yml b/modules/nf-core/snakemake/meta.yml index 2db26afda00f..71d94dd4609f 100644 --- a/modules/nf-core/snakemake/meta.yml +++ b/modules/nf-core/snakemake/meta.yml @@ -1,8 +1,7 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/yaml-schema.json name: "snakemake" -description: The Snakemake workflow management system is a tool to create reproducible - and scalable data analyses. This module runs a simple Snakemake pipeline based on - input snakefile. Expect many limitations." +description: The Snakemake workflow management system is a tool to create + reproducible and scalable data analyses. This module runs a simple Snakemake + pipeline based on input snakefile. Expect many limitations." keywords: - snakemake - workflow @@ -39,7 +38,6 @@ input: Snakefile to use with Snakemake. This is required for proper execution of Snakemake. ontologies: [] output: - #Only when we have meta outputs: - - meta: type: map @@ -59,16 +57,31 @@ output: e.g. [ id:'test', single_end:false ] - .snakemake: type: directory - description: Hidden directory containing Snakemake execution logs and metadata + description: Hidden directory containing Snakemake execution logs and + metadata pattern: ".snakemake" ontologies: [] + versions_snakemake: + - - ${task.process}: + type: string + description: The name of the process + - snakemake: + type: string + description: The name of the tool + - "snakemake --version": + type: eval + description: The expression to obtain the version of the tool +topics: versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - - ${task.process}: + type: string + description: The name of the process + - snakemake: + type: string + description: The name of the tool + - "snakemake --version": + type: eval + description: The expression to obtain the version of the tool authors: - "@adamrtalbot" maintainers: diff --git a/modules/nf-core/snakemake/tests/main.nf.test b/modules/nf-core/snakemake/tests/main.nf.test index 06205f0dea99..fa99e697a5ef 100644 --- a/modules/nf-core/snakemake/tests/main.nf.test +++ b/modules/nf-core/snakemake/tests/main.nf.test @@ -18,7 +18,7 @@ nextflow_process { [] ] // Snakefile - Channel.of(''' + channel.of(''' rule all: input: "hello.txt" @@ -42,12 +42,57 @@ rule hello_world: } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out.outputs, process.out.versions).match() } + { assert snapshot( + process.out.outputs, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } - } + test("Should run without failures - stub") { + options "-stub" + when { + process { + """ + // Input file + input[0] = [ + [ id: 'input'], + [] + ] +// Snakefile + channel.of(''' +rule all: + input: "hello.txt" + +rule hello_world: + output: "hello.txt" + shell: "echo Hello World > hello.txt" + +''' + ) + .collectFile(name: 'Snakefile') + .map { file -> + [ + [id: 'Snakefile'], + file + ]} + .set{ snakefile } + + input[1] = snakefile + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot( + process.out.outputs, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } } diff --git a/modules/nf-core/snakemake/tests/main.nf.test.snap b/modules/nf-core/snakemake/tests/main.nf.test.snap index cfd2ee688320..f10a74efa064 100644 --- a/modules/nf-core/snakemake/tests/main.nf.test.snap +++ b/modules/nf-core/snakemake/tests/main.nf.test.snap @@ -1,4 +1,25 @@ { + "Should run without failures - stub": { + "content": [ + [ + + ], + { + "versions_snakemake": [ + [ + "SNAKEMAKE", + "snakemake", + "9.14.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-28T17:17:18.329663" + }, "Should run without failures": { "content": [ [ @@ -9,10 +30,20 @@ "hello.txt:md5,e59ff97941044f85df5297e1c302d260" ] ], - [ - "versions.yml:md5,91f038cba572e2b7b6dfe06e0e088ce5" - ] + { + "versions_snakemake": [ + [ + "SNAKEMAKE", + "snakemake", + "9.14.0" + ] + ] + } ], - "timestamp": "2023-08-17T14:14:11+0000" + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-28T17:17:01.780244" } } \ No newline at end of file From b8c8f8542333ac6b801938fac04ecf0aa6bd7067 Mon Sep 17 00:00:00 2001 From: Felix Lenner <52530259+fellen31@users.noreply.github.com> Date: Fri, 5 Dec 2025 12:17:27 +0100 Subject: [PATCH 17/83] fix sambamba depth stub version (#9509) * fix stub version * stray module --- modules/nf-core/sambamba/depth/main.nf | 2 +- .../nf-core/sambamba/depth/tests/main.nf.test | 10 ++++- .../sambamba/depth/tests/main.nf.test.snap | 40 +++++++++++++------ 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/modules/nf-core/sambamba/depth/main.nf b/modules/nf-core/sambamba/depth/main.nf index e1404c7b0dba..42a1a80a323a 100644 --- a/modules/nf-core/sambamba/depth/main.nf +++ b/modules/nf-core/sambamba/depth/main.nf @@ -50,7 +50,7 @@ process SAMBAMBA_DEPTH { cat <<-END_VERSIONS > versions.yml "${task.process}": - sambamba: \$(sambamba --version) + sambamba: \$(echo \$(sambamba --version 2>&1) | awk '{print \$2}' ) END_VERSIONS """ } diff --git a/modules/nf-core/sambamba/depth/tests/main.nf.test b/modules/nf-core/sambamba/depth/tests/main.nf.test index 3f51059861b7..3f6fce50be03 100644 --- a/modules/nf-core/sambamba/depth/tests/main.nf.test +++ b/modules/nf-core/sambamba/depth/tests/main.nf.test @@ -30,7 +30,10 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out, + process.out.versions.collect{ path(it).yaml } + ).match() } ) } } @@ -85,7 +88,10 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out, + process.out.versions.collect{ path(it).yaml } + ).match() } ) } } diff --git a/modules/nf-core/sambamba/depth/tests/main.nf.test.snap b/modules/nf-core/sambamba/depth/tests/main.nf.test.snap index 7f4951e62acb..d1eb47aaa682 100644 --- a/modules/nf-core/sambamba/depth/tests/main.nf.test.snap +++ b/modules/nf-core/sambamba/depth/tests/main.nf.test.snap @@ -29,10 +29,10 @@ } ], "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2025-12-03T15:57:58.097957" + "timestamp": "2025-12-05T12:03:11.190921915" }, "test-sambamba-depth": { "content": [ @@ -61,13 +61,20 @@ "versions": [ "versions.yml:md5,6e2f38cc3306b1ea59da275d9de28d57" ] - } + }, + [ + { + "SAMBAMBA_DEPTH": { + "sambamba": "1.0.1" + } + } + ] ], "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2025-12-03T15:57:42.031913" + "timestamp": "2025-12-05T12:03:07.689091449" }, "test-sambamba-depth-stub": { "content": [ @@ -82,7 +89,7 @@ ] ], "1": [ - "versions.yml:md5,cc89620fa5c4f3af3aebf53eadd3edce" + "versions.yml:md5,6e2f38cc3306b1ea59da275d9de28d57" ], "bed": [ [ @@ -94,14 +101,21 @@ ] ], "versions": [ - "versions.yml:md5,cc89620fa5c4f3af3aebf53eadd3edce" + "versions.yml:md5,6e2f38cc3306b1ea59da275d9de28d57" ] - } + }, + [ + { + "SAMBAMBA_DEPTH": { + "sambamba": "1.0.1" + } + } + ] ], "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2025-12-03T15:58:13.647811" + "timestamp": "2025-12-05T12:03:14.737096819" } } \ No newline at end of file From 6c99c792acbb2eced474b75ac4ba6e1789f83412 Mon Sep 17 00:00:00 2001 From: Sebastian Uhrig Date: Fri, 5 Dec 2025 14:14:24 +0100 Subject: [PATCH 18/83] anota2seq: wrong variable name for batch assignment (#9511) rename variable --- modules/nf-core/anota2seq/anota2seqrun/templates/anota2seqrun.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nf-core/anota2seq/anota2seqrun/templates/anota2seqrun.r b/modules/nf-core/anota2seq/anota2seqrun/templates/anota2seqrun.r index c60eba35cc3c..a26e19a017ab 100644 --- a/modules/nf-core/anota2seq/anota2seqrun/templates/anota2seqrun.r +++ b/modules/nf-core/anota2seq/anota2seqrun/templates/anota2seqrun.r @@ -319,7 +319,7 @@ anota2seqDataSetFromMatrix_args <- list( ) if (! is.null(opt\$samples_batch_col)){ - anota2seqDataSetFromMatrix_args\$batchVec <- samples[rnaseq_samples, opt\$samples_batch_col] + anota2seqDataSetFromMatrix_args\$batchVec <- sample.sheet[rnaseq_samples, opt\$samples_batch_col] } ads <- do.call(anota2seqDataSetFromMatrix, anota2seqDataSetFromMatrix_args) From 28bea76c424d085df20dbdfbf4ba11ee905195c8 Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Fri, 5 Dec 2025 13:59:27 +0000 Subject: [PATCH 19/83] fix(anota2seq): add gene IDs and handle empty results (#9510) - Add missing gene_id_col parameter definition (defaults to 'gene_id') - Include gene IDs as first column in all results tables using configurable column name - Only write output files when there are significant results to avoid empty files - Mark all results TSV outputs as optional since they're conditionally created - Update test to use buffering results instead of empty mRNA_abundance results - Update test snapshots with new file formats including gene_id column This ensures anota2seq results are consistent with other modules and include gene identifiers for downstream analysis, while gracefully handling cases where no genes pass significance thresholds. Co-authored-by: Sebastian Uhrig --- .../nf-core/anota2seq/anota2seqrun/main.nf | 10 +++---- .../anota2seqrun/templates/anota2seqrun.r | 26 +++++++++++++------ .../anota2seq/anota2seqrun/tests/main.nf.test | 2 +- .../anota2seqrun/tests/main.nf.test.snap | 14 +++++----- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/modules/nf-core/anota2seq/anota2seqrun/main.nf b/modules/nf-core/anota2seq/anota2seqrun/main.nf index eb15ed1d06c4..c08e2f85bcbb 100644 --- a/modules/nf-core/anota2seq/anota2seqrun/main.nf +++ b/modules/nf-core/anota2seq/anota2seqrun/main.nf @@ -12,11 +12,11 @@ process ANOTA2SEQ_ANOTA2SEQRUN { tuple val(meta2), path(samplesheet), path(counts) output: - tuple val(meta), path("*.translated_mRNA.anota2seq.results.tsv") , emit: translated_mrna - tuple val(meta), path("*.total_mRNA.anota2seq.results.tsv") , emit: total_mrna - tuple val(meta), path("*.translation.anota2seq.results.tsv") , emit: translation - tuple val(meta), path("*.buffering.anota2seq.results.tsv") , emit: buffering - tuple val(meta), path("*.mRNA_abundance.anota2seq.results.tsv") , emit: mrna_abundance + tuple val(meta), path("*.translated_mRNA.anota2seq.results.tsv") , emit: translated_mrna, optional: true + tuple val(meta), path("*.total_mRNA.anota2seq.results.tsv") , emit: total_mrna, optional: true + tuple val(meta), path("*.translation.anota2seq.results.tsv") , emit: translation, optional: true + tuple val(meta), path("*.buffering.anota2seq.results.tsv") , emit: buffering, optional: true + tuple val(meta), path("*.mRNA_abundance.anota2seq.results.tsv") , emit: mrna_abundance, optional: true tuple val(meta), path("*.Anota2seqDataSet.rds") , emit: rdata tuple val(meta), path("*.fold_change.png") , emit: fold_change_plot tuple val(meta), path("*.interaction_p_distribution.pdf") , emit: interaction_p_distribution_plot , optional: true diff --git a/modules/nf-core/anota2seq/anota2seqrun/templates/anota2seqrun.r b/modules/nf-core/anota2seq/anota2seqrun/templates/anota2seqrun.r index a26e19a017ab..8266999226b6 100644 --- a/modules/nf-core/anota2seq/anota2seqrun/templates/anota2seqrun.r +++ b/modules/nf-core/anota2seq/anota2seqrun/templates/anota2seqrun.r @@ -116,6 +116,7 @@ opt <- list( reference_level = '$reference', target_level = '$target', sample_id_col = "sample", + gene_id_col = "gene_id", samples_pairing_col = NULL, samples_batch_col = NULL, subset_to_contrast_samples = FALSE, @@ -366,14 +367,23 @@ for (analysis in c("translated mRNA", "total mRNA", "translation", "buffering", selContrast = 1 ) - write.table( - output, - file = paste(opt\$output_prefix, sub(' ', '_', analysis), 'anota2seq.results.tsv', sep = '.'), - col.names = TRUE, - row.names = FALSE, - sep = '\t', - quote = FALSE - ) + # Only write file if there are results + if (!is.null(output) && nrow(output) > 0) { + # Add gene IDs as the first column + output_with_genes <- cbind( + setNames(data.frame(rownames(output)), opt\$gene_id_col), + output + ) + + write.table( + output_with_genes, + file = paste(opt\$output_prefix, sub(' ', '_', analysis), 'anota2seq.results.tsv', sep = '.'), + col.names = TRUE, + row.names = FALSE, + sep = '\t', + quote = FALSE + ) + } } # Fold change plot diff --git a/modules/nf-core/anota2seq/anota2seqrun/tests/main.nf.test b/modules/nf-core/anota2seq/anota2seqrun/tests/main.nf.test index 0dca16564931..037d2ba228da 100644 --- a/modules/nf-core/anota2seq/anota2seqrun/tests/main.nf.test +++ b/modules/nf-core/anota2seq/anota2seqrun/tests/main.nf.test @@ -38,7 +38,7 @@ nextflow_process { process.out.translated_mrna, process.out.total_mrna, process.out.translation, - process.out.mrna_abundance, + process.out.buffering, process.out.versions, file(process.out.fold_change_plot[0][1]).name, file(process.out.interaction_p_distribution_plot[0][1]).name, diff --git a/modules/nf-core/anota2seq/anota2seqrun/tests/main.nf.test.snap b/modules/nf-core/anota2seq/anota2seqrun/tests/main.nf.test.snap index b958196f46bc..d9712e2ef44d 100644 --- a/modules/nf-core/anota2seq/anota2seqrun/tests/main.nf.test.snap +++ b/modules/nf-core/anota2seq/anota2seqrun/tests/main.nf.test.snap @@ -6,7 +6,7 @@ { "id": "treatment_vs_control" }, - "treatment_vs_control.translated_mRNA.anota2seq.results.tsv:md5,2c8a7dc1841d2852fc68e5d65e89a8e1" + "treatment_vs_control.translated_mRNA.anota2seq.results.tsv:md5,e777e335d484831520e53c51db75a47c" ] ], [ @@ -14,7 +14,7 @@ { "id": "treatment_vs_control" }, - "treatment_vs_control.total_mRNA.anota2seq.results.tsv:md5,69778181d0ec4f50c11c99dfed7e9090" + "treatment_vs_control.total_mRNA.anota2seq.results.tsv:md5,ea8044585fcbf133b284e7a96bf2a4a8" ] ], [ @@ -22,7 +22,7 @@ { "id": "treatment_vs_control" }, - "treatment_vs_control.translation.anota2seq.results.tsv:md5,28dca3b6017569e8a8a0702714e7451c" + "treatment_vs_control.translation.anota2seq.results.tsv:md5,99045a6fca60386e8cb5a31a49491688" ] ], [ @@ -30,7 +30,7 @@ { "id": "treatment_vs_control" }, - "treatment_vs_control.mRNA_abundance.anota2seq.results.tsv:md5,68b329da9893e34099c7d8ad5cb9c940" + "treatment_vs_control.buffering.anota2seq.results.tsv:md5,d900d02201c6703aba62cd30a10d2ded" ] ], [ @@ -52,9 +52,9 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-06-01T14:34:20.085223495" + "timestamp": "2025-12-05T12:21:54.259548595" } } \ No newline at end of file From dabd880c0acc859f861396dc2856ffc3042d2c06 Mon Sep 17 00:00:00 2001 From: Anabella Trigila <18577080+atrigila@users.noreply.github.com> Date: Sun, 7 Dec 2025 09:58:35 -0300 Subject: [PATCH 20/83] =?UTF-8?q?fix(decoupler):=20reorder=20imports=20and?= =?UTF-8?q?=20ensure=20environment=20variables=20are=20=E2=80=A6=20(#9516)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(decoupler): reorder imports and ensure environment variables are set before importing modules --- .../decoupler/templates/decoupler.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/modules/nf-core/decoupler/decoupler/templates/decoupler.py b/modules/nf-core/decoupler/decoupler/templates/decoupler.py index 0618c7e14c63..212d2159b2f8 100644 --- a/modules/nf-core/decoupler/decoupler/templates/decoupler.py +++ b/modules/nf-core/decoupler/decoupler/templates/decoupler.py @@ -1,19 +1,18 @@ #!/usr/bin/env python3 -import argparse import os -import shlex -import sys - -import decoupler as dc -import matplotlib.pyplot as plt -import numba -import pandas as pd +# This must execute before decoupler is imported, so the env vars are visible when Numba decides whether to cache +os.environ["NUMBA_DISABLE_CACHE"] = "1" os.environ["NUMBA_CACHE_DIR"] = "./tmp" os.environ["MPLCONFIGDIR"] = "./tmp" -os.environ["NUMBA_DISABLE_CACHE"] = "1" -numba.config.DISABLE_CACHE = True +import argparse +import shlex +import sys + +import decoupler as dc # noqa: E402 +import matplotlib.pyplot as plt +import pandas as pd # noqa: E402 mat = pd.read_csv("${mat}", sep="\t", index_col=0) net = pd.read_csv("${net}", sep="\t") From 2d52823dabd820a93ba47ec3693eb36d912cc78d Mon Sep 17 00:00:00 2001 From: Felix Lenner <52530259+fellen31@users.noreply.github.com> Date: Sun, 7 Dec 2025 18:01:40 +0100 Subject: [PATCH 21/83] Add strdrop/build (#9512) Add strdrop build --- modules/nf-core/strdrop/build/environment.yml | 10 ++ modules/nf-core/strdrop/build/main.nf | 34 ++++++ modules/nf-core/strdrop/build/meta.yml | 68 ++++++++++++ .../nf-core/strdrop/build/tests/main.nf.test | 101 +++++++++++++++++ .../strdrop/build/tests/main.nf.test.snap | 102 ++++++++++++++++++ 5 files changed, 315 insertions(+) create mode 100644 modules/nf-core/strdrop/build/environment.yml create mode 100644 modules/nf-core/strdrop/build/main.nf create mode 100644 modules/nf-core/strdrop/build/meta.yml create mode 100644 modules/nf-core/strdrop/build/tests/main.nf.test create mode 100644 modules/nf-core/strdrop/build/tests/main.nf.test.snap diff --git a/modules/nf-core/strdrop/build/environment.yml b/modules/nf-core/strdrop/build/environment.yml new file mode 100644 index 000000000000..6bb6e068535a --- /dev/null +++ b/modules/nf-core/strdrop/build/environment.yml @@ -0,0 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - conda-forge::pip=25.3 + - conda-forge::python=3.14.1 + - pip: + - strdrop==0.3 diff --git a/modules/nf-core/strdrop/build/main.nf b/modules/nf-core/strdrop/build/main.nf new file mode 100644 index 000000000000..61f00927be46 --- /dev/null +++ b/modules/nf-core/strdrop/build/main.nf @@ -0,0 +1,34 @@ +process STRDROP_BUILD { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/4f/4fc3114f6d67fadb826981d29ae67f8564ee81283184893c2db677d919b5b32d/data': + 'community.wave.seqera.io/library/pip_strdrop:df8d5dc993ea6848' }" + + input: + tuple val(meta), path(training_set, stageAs: 'input/*') + + output: + tuple val(meta), path("*.json"), emit: json + tuple val("${task.process}"), val('strdrop'), eval("strdrop --version | sed 's/.* //g'"), topic: versions, emit: versions_strdrop + + when: + task.ext.when == null || task.ext.when + + script: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + strdrop \\ + build \\ + --training-set ./input \\ + ${prefix}.json + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.json + """ +} diff --git a/modules/nf-core/strdrop/build/meta.yml b/modules/nf-core/strdrop/build/meta.yml new file mode 100644 index 000000000000..64f47d2a34af --- /dev/null +++ b/modules/nf-core/strdrop/build/meta.yml @@ -0,0 +1,68 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "strdrop_build" +description: Build reference json from sequencing coverage in STR VCFs +keywords: + - str + - vcf + - lrs +tools: + - "strdrop": + description: "Flag STR coverage drops in LRS data" + homepage: "https://github.com/dnil/strdrop" + documentation: "https://github.com/dnil/strdrop/blob/main/docs/README.md" + tool_dev_url: "https://github.com/dnil/strdrop" + licence: ["MIT"] + identifier: "" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - training_set: + type: file + description: Input VCF training set files + pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" + ontologies: + - edam: "http://edamontology.org/format_3016" # VCF + - edam: "http://edamontology.org/format_3020" # BCF +output: + json: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.json": + type: file + description: Output reference json file + pattern: "*.json" + ontologies: + - edam: "http://edamontology.org/format_3464" # JSON + versions_strdrop: + - - ${task.process}: + type: string + description: The name of the process + - strdrop: + type: string + description: The name of the tool + - strdrop --version | sed 's/.* //g': + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - strdrop: + type: string + description: The name of the tool + - strdrop --version | sed 's/.* //g': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@fellen31" +maintainers: + - "@fellen31" diff --git a/modules/nf-core/strdrop/build/tests/main.nf.test b/modules/nf-core/strdrop/build/tests/main.nf.test new file mode 100644 index 000000000000..10d999ab9801 --- /dev/null +++ b/modules/nf-core/strdrop/build/tests/main.nf.test @@ -0,0 +1,101 @@ +nextflow_process { + + name "Test Process STRDROP_BUILD" + script "../main.nf" + process "STRDROP_BUILD" + + tag "modules" + tag "modules_nfcore" + tag "strdrop" + tag "strdrop/build" + tag "samtools/faidx" + tag "gunzip" + tag "trgt/genotype" + + setup { + run("GUNZIP"){ + script "../../../gunzip/main.nf" + process { + """ + input[0] = [ + [ id : 'chr22' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22_chr22_KI270734v1_random/sequence/genome.fa.gz', checkIfExists: true) + ] + """ + } + } + run("SAMTOOLS_FAIDX"){ + script "../../../samtools/faidx/main.nf" + process { + """ + input[0] = GUNZIP.out.gunzip + input[1] = [[],[]] + input[2] = false + """ + } + } + run("TRGT_GENOTYPE"){ + script "../../../trgt/genotype/main.nf" + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/bam/test.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/bam/test.sorted.bam.bai', checkIfExists: true), + 'XX' + ] + input[1] = GUNZIP.out.gunzip + input[2] = SAMTOOLS_FAIDX.out.fai + input[3] = Channel.of('chr22\t18890357\t18890451\tID=TEST;MOTIFS=AT;STRUC=(AT)n') + .collectFile(name : 'repeats.bed', newLine: false) + .map { file -> [ [ id : 'chr22' ], file ] } + """ + } + } + } + + test("test") { + when { + process { + """ + input[0] = TRGT_GENOTYPE.out.vcf + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out, + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } + + test("test-stub") { + + options "-stub" + + when { + process { + """ + input[0] = TRGT_GENOTYPE.out.vcf + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out, + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } +} diff --git a/modules/nf-core/strdrop/build/tests/main.nf.test.snap b/modules/nf-core/strdrop/build/tests/main.nf.test.snap new file mode 100644 index 000000000000..b53395fc369e --- /dev/null +++ b/modules/nf-core/strdrop/build/tests/main.nf.test.snap @@ -0,0 +1,102 @@ +{ + "test": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.json:md5,e918b92effa7c7c4696f3ae80e51d0d5" + ] + ], + "1": [ + [ + "STRDROP_BUILD", + "strdrop", + "0.3" + ] + ], + "json": [ + [ + { + "id": "test" + }, + "test.json:md5,e918b92effa7c7c4696f3ae80e51d0d5" + ] + ], + "versions_strdrop": [ + [ + "STRDROP_BUILD", + "strdrop", + "0.3" + ] + ] + }, + { + "versions_strdrop": [ + [ + "STRDROP_BUILD", + "strdrop", + "0.3" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-06T11:11:57.601817569" + }, + "test-stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "STRDROP_BUILD", + "strdrop", + "0.3" + ] + ], + "json": [ + [ + { + "id": "test" + }, + "test.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_strdrop": [ + [ + "STRDROP_BUILD", + "strdrop", + "0.3" + ] + ] + }, + { + "versions_strdrop": [ + [ + "STRDROP_BUILD", + "strdrop", + "0.3" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-06T11:12:03.26800462" + } +} \ No newline at end of file From 60239ed74433f28c809d474d407dbb8e30cf6860 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 01:59:59 +0000 Subject: [PATCH 22/83] chore(deps): update infrastructural dependencies --- .github/actions/nf-test-action/action.yml | 2 +- .github/workflows/clean-up.yml | 2 +- .github/workflows/close-wishlist.yml | 2 +- .github/workflows/fix-linting.yml | 2 +- .github/workflows/lint.yml | 10 +++++----- .github/workflows/nf-test-gpu.yml | 4 ++-- .github/workflows/nf-test.yml | 4 ++-- .github/workflows/pytest-workflow.yml | 6 +++--- .github/workflows/reminder.yml | 2 +- .github/workflows/skipped-nf-test-gpu.yml | 2 +- .github/workflows/skipped-nf-test.yml | 2 +- .github/workflows/update-gpu-snapshot.yml | 4 ++-- .github/workflows/update-sentieon-snapshot.yml | 4 ++-- .github/workflows/wave.yml | 6 +++--- 14 files changed, 26 insertions(+), 26 deletions(-) diff --git a/.github/actions/nf-test-action/action.yml b/.github/actions/nf-test-action/action.yml index beb5493c026f..696bee416d33 100644 --- a/.github/actions/nf-test-action/action.yml +++ b/.github/actions/nf-test-action/action.yml @@ -17,7 +17,7 @@ inputs: runs: using: "composite" steps: - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5 with: distribution: "temurin" java-version: "17" diff --git a/.github/workflows/clean-up.yml b/.github/workflows/clean-up.yml index c818a51463cd..3bd20444d674 100644 --- a/.github/workflows/clean-up.yml +++ b/.github/workflows/clean-up.yml @@ -11,7 +11,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10 + - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10 with: stale-issue-message: "This issue has been tagged as awaiting-changes or awaiting-feedback by an @nf-core/modules contributor. Remove stale label or add a comment otherwise this issue will be closed in 20 days." stale-pr-message: "This PR has been tagged as awaiting-changes or awaiting-feedback by an @nf-core/modules contributor. Remove stale label or add a comment if it is still useful." diff --git a/.github/workflows/close-wishlist.yml b/.github/workflows/close-wishlist.yml index 4bc64eab04b3..f4e6767037f5 100644 --- a/.github/workflows/close-wishlist.yml +++ b/.github/workflows/close-wishlist.yml @@ -10,7 +10,7 @@ jobs: permissions: issues: write steps: - - uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10 + - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10 with: stale-issue-message: "This issue has been tagged as wishlist and no one has assigned themselves to it within a year. It will be closed in 10 days unless someone assigns themselves to it." close-issue-message: "This issue was closed because it has been tagged as wishlist and no one worked on it for over a year." diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index 460b80c6761c..f9f3f8a2f2ed 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: token: ${{ secrets.nf_core_bot_auth_token }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 91d36ab47748..d5dd09b83e6b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -35,7 +35,7 @@ jobs: pre-commit: runs-on: ${{ github.event.inputs.runners || github.run_number > 1 && 'ubuntu-latest' || 'self-hosted' }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - name: Run prek uses: j178/prek-action@91fd7d7cf70ae1dee9f4f44e7dfa5d1073fe6623 # v1 @@ -62,7 +62,7 @@ jobs: sudo rm -rf ./* || true sudo rm -rf ./.* || true - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 2 # To retrieve the preceding commit. @@ -126,7 +126,7 @@ jobs: run: | sudo rm -rf ./* || true sudo rm -rf ./.* || true - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - name: Set up Python uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6 with: @@ -143,7 +143,7 @@ jobs: - name: Install pip run: python -m pip install --upgrade pip - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5 with: distribution: "temurin" java-version: "17" @@ -174,7 +174,7 @@ jobs: run: | sudo rm -rf ./* || true sudo rm -rf ./.* || true - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - name: Set up Python uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6 with: diff --git a/.github/workflows/nf-test-gpu.yml b/.github/workflows/nf-test-gpu.yml index f1e007d8cb2b..f3e9629e144f 100644 --- a/.github/workflows/nf-test-gpu.yml +++ b/.github/workflows/nf-test-gpu.yml @@ -53,7 +53,7 @@ jobs: rm -rf ./* || true rm -rf ./.??* || true ls -la ./ - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 0 @@ -105,7 +105,7 @@ jobs: TOTAL_SHARDS: ${{ needs.nf-test-changes.outputs.total_shards }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 0 - name: test cuda diff --git a/.github/workflows/nf-test.yml b/.github/workflows/nf-test.yml index 6b5932791ac1..b416b59ef959 100644 --- a/.github/workflows/nf-test.yml +++ b/.github/workflows/nf-test.yml @@ -51,7 +51,7 @@ jobs: rm -rf ./* || true rm -rf ./.??* || true ls -la ./ - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 0 @@ -112,7 +112,7 @@ jobs: filtered_paths: ${{ steps.filter.outputs.filtered_paths }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 0 diff --git a/.github/workflows/pytest-workflow.yml b/.github/workflows/pytest-workflow.yml index 1620d463d632..990a6409c2a7 100644 --- a/.github/workflows/pytest-workflow.yml +++ b/.github/workflows/pytest-workflow.yml @@ -43,7 +43,7 @@ jobs: modules: ${{ steps.tags.outputs.modules }} subworkflows: ${{ steps.tags.outputs.subworkflows }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 2 # To retrieve the preceding commit. @@ -229,7 +229,7 @@ jobs: env: NXF_ANSI_LOG: false steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - name: Set up Python uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6 @@ -247,7 +247,7 @@ jobs: - name: Install Python dependencies run: python -m pip install --upgrade pip pytest-workflow cryptography - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5 with: distribution: "temurin" java-version: "17" diff --git a/.github/workflows/reminder.yml b/.github/workflows/reminder.yml index f58cfb754ee7..6ff0a02e92ac 100644 --- a/.github/workflows/reminder.yml +++ b/.github/workflows/reminder.yml @@ -10,7 +10,7 @@ jobs: permissions: issues: write steps: - - uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10 + - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10 with: stale-issue-message: "This is a reminder that you assigned yourself to this issue to create a new module / new subworkflow. Please remove yourself from the Assignees if you do not plan to work on this anymore." days-before-stale: 178 diff --git a/.github/workflows/skipped-nf-test-gpu.yml b/.github/workflows/skipped-nf-test-gpu.yml index cba74605d221..9a6559c66d70 100644 --- a/.github/workflows/skipped-nf-test-gpu.yml +++ b/.github/workflows/skipped-nf-test-gpu.yml @@ -20,7 +20,7 @@ jobs: outputs: only-meta: ${{ steps.only-meta-check.outputs.only-meta }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3 id: changes with: diff --git a/.github/workflows/skipped-nf-test.yml b/.github/workflows/skipped-nf-test.yml index bc0d09e3115a..8616fcaee47a 100644 --- a/.github/workflows/skipped-nf-test.yml +++ b/.github/workflows/skipped-nf-test.yml @@ -20,7 +20,7 @@ jobs: outputs: only-meta: ${{ steps.only-meta-check.outputs.only-meta }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3 id: changes with: diff --git a/.github/workflows/update-gpu-snapshot.yml b/.github/workflows/update-gpu-snapshot.yml index 173a95d92374..a936f54c50ba 100644 --- a/.github/workflows/update-gpu-snapshot.yml +++ b/.github/workflows/update-gpu-snapshot.yml @@ -28,7 +28,7 @@ jobs: comment-id: ${{ github.event.comment.id }} reactions: eyes # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: token: ${{ secrets.nf_core_bot_auth_token }} @@ -55,7 +55,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.nf_core_bot_auth_token }} - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5 with: distribution: "temurin" java-version: "17" diff --git a/.github/workflows/update-sentieon-snapshot.yml b/.github/workflows/update-sentieon-snapshot.yml index fabdf83554b0..a407402f7b32 100644 --- a/.github/workflows/update-sentieon-snapshot.yml +++ b/.github/workflows/update-sentieon-snapshot.yml @@ -31,7 +31,7 @@ jobs: comment-id: ${{ github.event.comment.id }} reactions: eyes # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: token: ${{ secrets.nf_core_bot_auth_token }} @@ -58,7 +58,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.nf_core_bot_auth_token }} - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5 with: distribution: "temurin" java-version: "17" diff --git a/.github/workflows/wave.yml b/.github/workflows/wave.yml index 866815964757..0de6ad1bbbe4 100644 --- a/.github/workflows/wave.yml +++ b/.github/workflows/wave.yml @@ -27,7 +27,7 @@ jobs: conda-matrix: ${{ steps.conda-diff.outputs.all_changed_files }} dockerfile-matrix: ${{ steps.docker-diff.outputs.all_changed_files }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - name: Find conda differences id: conda-diff @@ -63,7 +63,7 @@ jobs: profile: [docker, singularity] platform: ["linux/amd64", "linux/arm64"] steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - name: Install wave-cli run: | @@ -103,7 +103,7 @@ jobs: # profile: [docker] platform: ["linux/amd64", "linux/arm64"] steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - name: Install wave-cli run: | From 7b3c6f482aaab5beeb0d381b40a33fd0d515163b Mon Sep 17 00:00:00 2001 From: Henry Webel Date: Mon, 8 Dec 2025 09:28:17 +0100 Subject: [PATCH 23/83] =?UTF-8?q?=F0=9F=94=A7=20update=20image=20and=20bio?= =?UTF-8?q?conda=20container=20for=20VueGen=20to=20latest=20version=20(#92?= =?UTF-8?q?01)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🔧 update image and bioconda container to latest version * ✅ update test snapshots * :bug: fix display of version of vuegen - had no command line interface option to display version, see https://github.com/Multiomics-Analytics-Group/vuegen/issues/167 * :art: display versions.yml content in snapshots * 🔧 add Dockerfile to install lastet PyPI vuegen version - does not pass hadolint(er) as of now * 🚧 add wave containers * :fire: remove README again * :fire: remove Dockerfile again * 🚧 try to follow Mahesh's advice * :bug: add explicit cache directory * 🔧 bump to Python 3.12 and remove channel prefix * :wrench: specify singularity image with https ... as specified in the docs: https://nf-co.re/docs/tutorials/nf-core_components/using_seqera_containers * 🚧 set user specified R libarary folder * ⏪ make docker and conda work again (using nf-core 3.5.1) * :wrench: switch again to custom docker image instead of wave - wave leads to too many custom installation issues * :bug: try to add font package * :fire: remove code moved to image - singularity runs in devcontainer * ⏪ add back conda quarto flag * :art: remove trailing whitespace * :art: format again * :art: hopefully the last trailing whitespace * :memo: document the build process and why the container is needed * Update image with nf-core one Co-authored-by: Matthias Hörtenhuber * Update container name Co-authored-by: Matthias Hörtenhuber * Apply suggestion from @mashehu * Apply suggestion from @mashehu --------- Co-authored-by: Famke Bäuerle <45968370+famosab@users.noreply.github.com> Co-authored-by: Matthias Hörtenhuber --- modules/nf-core/vuegen/Dockerfile | 52 +++++++++++++++++ modules/nf-core/vuegen/README.md | 22 +++++++ modules/nf-core/vuegen/environment.yml | 4 +- modules/nf-core/vuegen/main.nf | 32 +++++----- modules/nf-core/vuegen/tests/main.nf.test | 8 +-- .../nf-core/vuegen/tests/main.nf.test.snap | 58 +++++++++++-------- 6 files changed, 129 insertions(+), 47 deletions(-) create mode 100644 modules/nf-core/vuegen/Dockerfile create mode 100644 modules/nf-core/vuegen/README.md diff --git a/modules/nf-core/vuegen/Dockerfile b/modules/nf-core/vuegen/Dockerfile new file mode 100644 index 000000000000..5caf60567ae3 --- /dev/null +++ b/modules/nf-core/vuegen/Dockerfile @@ -0,0 +1,52 @@ +# Set the base image to the official Python 3.12 slim debian trixie image +FROM python:3.12-slim-trixie + + +# Disable manual feedback for apt-get, update package list, install security updates, +# and install packages (procps, and system dependencies for tinytex and kaleido). +# Then clean up the package list and remove the cache. +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get -y upgrade && \ + apt-get install -y --no-install-recommends \ + procps=2:4.0.4-9 \ + wget=1.25.0-2 \ + perl=5.40.1-6 \ + # #2.84.4-3~deb13u1 + libglib2.0-0t64=2.84.4-3~deb13u1 \ + libgdk-pixbuf-2.0-0=2.42.12+dfsg-4 \ + libfontconfig1=2.15.0-2.3 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install vuegen Python package +RUN pip install --no-cache-dir -U vuegen==0.5.1 + +# Create and switch to non-root user for security reasons +RUN useradd --create-home appuser +USER appuser + +# Set the working directory +WORKDIR /home/appuser + +# Install TinyTeX for pdf reports +SHELL ["/bin/bash", "-o", "pipefail", "-c"] +RUN perl -mFile::Find /dev/null && \ + wget -qO- "https://yihui.org/tinytex/install-bin-unix.sh" | sh && \ + ~/.TinyTeX/bin/*/tlmgr \ + install \ + koma-script \ + caption \ + luaotfload + +# Set permissions for the appuser home directory +RUN chmod -R 777 /home/appuser + +# Set environment variables for Quarto, dataframe_image, and TinyTeX. Also, get tracebacks from C crashes +ENV XDG_RUNTIME_DIR=/tmp \ + XDG_CACHE_HOME=/tmp/quarto_cache_home \ + XDG_DATA_HOME=/tmp/quarto_data_home \ + PATH="${PATH}:/home/appuser/bin" \ + TEXMFVAR=/tmp/texmf-var \ + TEXMFHOME=/tmp/texmf-home \ + PYTHONFAULTHANDLER=1 diff --git a/modules/nf-core/vuegen/README.md b/modules/nf-core/vuegen/README.md new file mode 100644 index 000000000000..ce103444a43d --- /dev/null +++ b/modules/nf-core/vuegen/README.md @@ -0,0 +1,22 @@ +# VueGen Module + +## Dockerimage + +The dockerimage is needed as both quarto and the TinyTeX distribution are installed +inside the container to make vuegen work properly. At runtime especially apptainer +does not support installing packages on the fly to read-only directories. + +```bash +#!/bin/bash +set -euo pipefail + +ORG="quay.io/nf-core" +VERSION="v0.5.1" + +# 1. Build & push the base image (nextflow version) +docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --push \ + -t ${ORG}/vuegen:${VERSION} \ + -f Dockerfile . +``` diff --git a/modules/nf-core/vuegen/environment.yml b/modules/nf-core/vuegen/environment.yml index 8eab2a170585..6dee2d2d963d 100644 --- a/modules/nf-core/vuegen/environment.yml +++ b/modules/nf-core/vuegen/environment.yml @@ -4,5 +4,5 @@ channels: - bioconda - conda-forge dependencies: - - bioconda::vuegen=0.3.2 - - python=3.11 + - python=3.12 + - vuegen=0.5.1 diff --git a/modules/nf-core/vuegen/main.nf b/modules/nf-core/vuegen/main.nf index ddc333fe5859..409ba207c46c 100644 --- a/modules/nf-core/vuegen/main.nf +++ b/modules/nf-core/vuegen/main.nf @@ -1,23 +1,23 @@ process VUEGEN { label 'process_single' conda "${moduleDir}/environment.yml" - container "dtu_biosustain_dsp/vuegen:v0.3.2-nextflow" + container "nf-core/vuegen:0.5.1" input: - val input_type - path input_path - val report_type + val input_type + path input_path + val report_type output: - path "*report", emit: output_folder - path "versions.yml", emit: versions + path "*report", emit: output_folder + path "versions.yml", emit: versions when: - task.ext.when == null || task.ext.when + task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - """ + def args = task.ext.args ?: '' + """ # Validate quarto_check flag if using a conda environment if [[ "${task.conda}" != "null" ]]; then QUARTO_CHECK_FLAG="--quarto_checks" @@ -27,28 +27,28 @@ process VUEGEN { # Execute VueGen based on the input type if [ "${input_type}" == "config" ]; then - echo "Running VueGen with config file: $input_path" - vuegen --config $input_path --report_type $report_type \$QUARTO_CHECK_FLAG $args + echo "Running VueGen with config file: ${input_path}" + vuegen --config ${input_path} --report_type ${report_type} \$QUARTO_CHECK_FLAG ${args} elif [ "${input_type}" == "directory" ]; then - echo "Running VueGen with directory: $input_path" - vuegen --directory $input_path --report_type $report_type \$QUARTO_CHECK_FLAG $args + echo "Running VueGen with directory: ${input_path}" + vuegen --directory ${input_path} --report_type ${report_type} \$QUARTO_CHECK_FLAG ${args} fi cat <<-END_VERSIONS > versions.yml "${task.process}": - vuegen: \$( vuegen --version | sed -e "s/vuegen //g" ) + vuegen: \$( python -c "import vuegen; print(vuegen.__version__)" ) END_VERSIONS """ stub: - """ + """ echo "STUB MODE: Creating a generic report directory" mkdir -p report touch report/report.txt cat <<-END_VERSIONS > versions.yml "${task.process}": - vuegen: \$( vuegen --version | sed -e "s/vuegen //g" ) + vuegen: \$( python -c "import vuegen; print(vuegen.__version__)" ) END_VERSIONS """ } diff --git a/modules/nf-core/vuegen/tests/main.nf.test b/modules/nf-core/vuegen/tests/main.nf.test index b11ba33f9ac3..40f7c7938f28 100644 --- a/modules/nf-core/vuegen/tests/main.nf.test +++ b/modules/nf-core/vuegen/tests/main.nf.test @@ -49,7 +49,7 @@ nextflow_process { "Static_Plots.py": path(process.out.output_folder[0] + "/sections/Plots/Static_Plots.py") .readLines()[0..3].sort().join('\n').md5() ], - versions: process.out.versions + versions: path(process.out.versions[0]).yaml, ]).match() } ) @@ -80,7 +80,7 @@ nextflow_process { "quarto_report.qmd": path(process.out.output_folder[0] + "/quarto_report.qmd") .readLines()[0..3].join('\n').md5() ], - versions: process.out.versions + versions: path(process.out.versions[0]).yaml ]).match() } ) @@ -111,7 +111,7 @@ nextflow_process { "quarto_report.qmd": path(process.out.output_folder[0] + "/quarto_report.qmd") .readLines()[0..3].sort().join('\n').md5() ], - versions: process.out.versions + versions: path(process.out.versions[0]).yaml, ]).match() } ) @@ -138,7 +138,7 @@ nextflow_process { assert snapshot( process.out.output_folder.collect { file(it).getName() } + process.out.output_files.collect { file(it).getName() }, - versions: process.out.versions + versions: path(process.out.versions[0]).yaml, ).match() } ) diff --git a/modules/nf-core/vuegen/tests/main.nf.test.snap b/modules/nf-core/vuegen/tests/main.nf.test.snap index ba5f6682404c..ea03a715d364 100644 --- a/modules/nf-core/vuegen/tests/main.nf.test.snap +++ b/modules/nf-core/vuegen/tests/main.nf.test.snap @@ -2,9 +2,11 @@ "vuegen - directory (HTML report) -stub": { "content": [ { - "versions": [ - "versions.yml:md5,c3e7ebc433dcacf3d15e1113fd44f5ec" - ] + "versions": { + "VUEGEN": { + "vuegen": "0.5.1" + } + } }, [ "report" @@ -12,9 +14,9 @@ ], "meta": { "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nextflow": "24.10.6" }, - "timestamp": "2025-04-22T09:34:45.900956" + "timestamp": "2025-10-20T13:25:42.669804" }, "vuegen - directory (HTML report)": { "content": [ @@ -24,16 +26,18 @@ "quarto_report.html": "0129d189059f27b3d2ff6f328cd18ef9", "quarto_report.qmd": "e60a379de892055748e4597f9d8c656c" }, - "versions": [ - "versions.yml:md5,c3e7ebc433dcacf3d15e1113fd44f5ec" - ] + "versions": { + "VUEGEN": { + "vuegen": "0.5.1" + } + } } ], "meta": { "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nextflow": "24.10.6" }, - "timestamp": "2025-04-22T09:04:23.56469" + "timestamp": "2025-10-20T13:24:59.558083" }, "vuegen - directory (PDF report)": { "content": [ @@ -43,37 +47,41 @@ "quarto_report.pdf": true, "quarto_report.qmd": "c447088ca2a435acf926ec5e95c51265" }, - "versions": [ - "versions.yml:md5,c3e7ebc433dcacf3d15e1113fd44f5ec" - ] + "versions": { + "VUEGEN": { + "vuegen": "0.5.1" + } + } } ], "meta": { "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nextflow": "24.10.6" }, - "timestamp": "2025-04-22T09:05:54.139709" + "timestamp": "2025-10-20T13:25:37.140787" }, "vuegen - directory (Streamlit report)": { "content": [ { "output_folder": true, "output_files": { - "Homepage.py": "Homepage.py:md5,483a41696c225663772d68ff2d664493", - "report_manager.py": "report_manager.py:md5,ed15eefa722b7a2f08cca016c0c8e28d", - "All_Formats.py": "e2a56e761eb537da8f9809cbc0b63a9d", - "Interactive_Plots.py": "3198216240ef9b86d5b1ed722bd9b31c", - "Static_Plots.py": "931fd04e2e49cb14d169747b6d5bbd1e" + "Homepage.py": "Homepage.py:md5,a46395bbdfb127463d51d8f601f2ad83", + "report_manager.py": "report_manager.py:md5,a683071ba8bc6e371c8617ef9c3fb84e", + "All_Formats.py": "1f61acc3ca34f6ff941c109d93570815", + "Interactive_Plots.py": "4857dc511178812e93c2037c8bbe04f4", + "Static_Plots.py": "ae9c2e46ae9a9e0e5e98fcce87cd7f80" }, - "versions": [ - "versions.yml:md5,c3e7ebc433dcacf3d15e1113fd44f5ec" - ] + "versions": { + "VUEGEN": { + "vuegen": "0.5.1" + } + } } ], "meta": { "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nextflow": "24.10.6" }, - "timestamp": "2025-04-22T09:03:48.375488" + "timestamp": "2025-10-20T13:19:47.56244" } } \ No newline at end of file From 6963d5066a5f11b5c24d652cf09fd928d76dbd92 Mon Sep 17 00:00:00 2001 From: "Diego Alvarez S." Date: Mon, 8 Dec 2025 07:20:45 -0300 Subject: [PATCH 24/83] qsv/cat: bump version (#9518) Bump qsv --- modules/nf-core/qsv/cat/environment.yml | 2 +- modules/nf-core/qsv/cat/main.nf | 4 +- .../nf-core/qsv/cat/tests/main.nf.test.snap | 40 +++++++++---------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/modules/nf-core/qsv/cat/environment.yml b/modules/nf-core/qsv/cat/environment.yml index f54de73117a5..f59f9517b681 100644 --- a/modules/nf-core/qsv/cat/environment.yml +++ b/modules/nf-core/qsv/cat/environment.yml @@ -3,4 +3,4 @@ channels: - conda-forge dependencies: - - conda-forge::qsv=5.1.0 + - conda-forge::qsv=10.0.0 diff --git a/modules/nf-core/qsv/cat/main.nf b/modules/nf-core/qsv/cat/main.nf index f29d1cf2f118..60459d196aa7 100644 --- a/modules/nf-core/qsv/cat/main.nf +++ b/modules/nf-core/qsv/cat/main.nf @@ -4,8 +4,8 @@ process QSV_CAT { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/86/864fcf1e6a250b588eaabd4df01334e44bc528fd29049c4fb24f7c56c8c33695/data' - : 'community.wave.seqera.io/library/qsv:5.1.0--9a6a0c23d3b279b5'}" + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/4a/4adf8970403a7d766891a9c777ada7fa8e063b260ea9c1245de99e3d8eae8c98/data' + : 'community.wave.seqera.io/library/qsv:10.0.0--60dd6b03afcbccdd'}" input: tuple val(meta), path(csv, name: 'inputs/in*/*') diff --git a/modules/nf-core/qsv/cat/tests/main.nf.test.snap b/modules/nf-core/qsv/cat/tests/main.nf.test.snap index 480018d1e172..7256a27c5d90 100644 --- a/modules/nf-core/qsv/cat/tests/main.nf.test.snap +++ b/modules/nf-core/qsv/cat/tests/main.nf.test.snap @@ -14,7 +14,7 @@ [ "QSV_CAT", "qsv", - "5.1.0" + "10.0.0" ] ], "csv": [ @@ -29,16 +29,16 @@ [ "QSV_CAT", "qsv", - "5.1.0" + "10.0.0" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-11-26T02:28:59.50810191" + "timestamp": "2025-12-08T01:07:39.025991777" }, "csv - rows - stub": { "content": [ @@ -55,7 +55,7 @@ [ "QSV_CAT", "qsv", - "5.1.0" + "10.0.0" ] ], "csv": [ @@ -70,16 +70,16 @@ [ "QSV_CAT", "qsv", - "5.1.0" + "10.0.0" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-11-25T19:00:56.129258083" + "timestamp": "2025-12-08T01:07:51.830197167" }, "tsv - rows": { "content": [ @@ -96,7 +96,7 @@ [ "QSV_CAT", "qsv", - "5.1.0" + "10.0.0" ] ], "csv": [ @@ -111,16 +111,16 @@ [ "QSV_CAT", "qsv", - "5.1.0" + "10.0.0" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-11-25T18:59:07.728469804" + "timestamp": "2025-12-08T01:07:12.428268622" }, "mixed - rows": { "content": [ @@ -137,7 +137,7 @@ [ "QSV_CAT", "qsv", - "5.1.0" + "10.0.0" ] ], "csv": [ @@ -152,16 +152,16 @@ [ "QSV_CAT", "qsv", - "5.1.0" + "10.0.0" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-11-26T02:32:06.053744117" + "timestamp": "2025-12-08T01:07:25.256267202" }, "csv - rows": { "content": [ @@ -178,7 +178,7 @@ [ "QSV_CAT", "qsv", - "5.1.0" + "10.0.0" ] ], "csv": [ @@ -193,15 +193,15 @@ [ "QSV_CAT", "qsv", - "5.1.0" + "10.0.0" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-11-25T18:59:04.02262118" + "timestamp": "2025-12-08T01:06:59.499708286" } } \ No newline at end of file From 76c51e77ac4f99b9e923a52f6c1607d0bf93a4ef Mon Sep 17 00:00:00 2001 From: Ramprasad Neethiraj <20065894+ramprasadn@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:06:55 +0100 Subject: [PATCH 25/83] Update haplogrep3 recipe to use topics (#9523) Co-authored-by: nf-core-bot --- modules/nf-core/haplogrep3/classify/main.nf | 14 +------ modules/nf-core/haplogrep3/classify/meta.yml | 26 +++++++++--- .../classify/tests/main.nf.test.snap | 40 +++++++++++++------ 3 files changed, 50 insertions(+), 30 deletions(-) diff --git a/modules/nf-core/haplogrep3/classify/main.nf b/modules/nf-core/haplogrep3/classify/main.nf index 056b0635fe09..712146369197 100644 --- a/modules/nf-core/haplogrep3/classify/main.nf +++ b/modules/nf-core/haplogrep3/classify/main.nf @@ -11,8 +11,8 @@ process HAPLOGREP3_CLASSIFY { tuple val(meta), path(inputfile) output: - tuple val(meta), path("*.txt"), emit: txt - path "versions.yml" , emit: versions + tuple val(meta) , path("*.txt") , emit: txt + tuple val("${task.process}"), val('haplogrep3'), eval("haplogrep3 | sed -n 's/.*Haplogrep 3 \\([0-9.]\\+\\).*/\\1/p'"), emit: versions_haplogrep3, topic: versions when: task.ext.when == null || task.ext.when @@ -26,22 +26,12 @@ process HAPLOGREP3_CLASSIFY { $args \\ --in $inputfile \\ --out ${prefix}.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - haplogrep3: \$(echo \$(haplogrep3 2>&1) | (sed '2!d') | (sed 's/Haplogrep 3 //')) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - haplogrep3: \$(echo \$(haplogrep3 2>&1) | (sed '2!d') | (sed 's/Haplogrep 3 //')) - END_VERSIONS """ } diff --git a/modules/nf-core/haplogrep3/classify/meta.yml b/modules/nf-core/haplogrep3/classify/meta.yml index c3c01d54d204..53e40aa6441e 100644 --- a/modules/nf-core/haplogrep3/classify/meta.yml +++ b/modules/nf-core/haplogrep3/classify/meta.yml @@ -35,13 +35,27 @@ output: description: text file with classification information pattern: "*.{txt}" ontologies: [] + versions_haplogrep3: + - - ${task.process}: + type: string + description: The process the versions were collected from + - haplogrep3: + type: string + description: The tool name + - haplogrep3 | sed -n 's/.*Haplogrep 3 \\([0-9.]\\+\\': + type: string + description: The command used to generate the version of the tool +topics: versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - - ${task.process}: + type: string + description: The process the versions were collected from + - haplogrep3: + type: string + description: The tool name + - haplogrep3 | sed -n 's/.*Haplogrep 3 \\([0-9.]\\+\\': + type: string + description: The command used to generate the version of the tool authors: - "@lucpen" maintainers: diff --git a/modules/nf-core/haplogrep3/classify/tests/main.nf.test.snap b/modules/nf-core/haplogrep3/classify/tests/main.nf.test.snap index d1a276d25e25..cce1f871563d 100644 --- a/modules/nf-core/haplogrep3/classify/tests/main.nf.test.snap +++ b/modules/nf-core/haplogrep3/classify/tests/main.nf.test.snap @@ -12,7 +12,11 @@ ] ], "1": [ - "versions.yml:md5,bd62c94d9b52732b89fbd979ded94a60" + [ + "HAPLOGREP3_CLASSIFY", + "haplogrep3", + "3.2.2" + ] ], "txt": [ [ @@ -23,16 +27,20 @@ "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,bd62c94d9b52732b89fbd979ded94a60" + "versions_haplogrep3": [ + [ + "HAPLOGREP3_CLASSIFY", + "haplogrep3", + "3.2.2" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-01-28T15:34:35.106097277" + "timestamp": "2025-12-08T14:14:20.562672125" }, "test-haplogrep3-classify": { "content": [ @@ -47,7 +55,11 @@ ] ], "1": [ - "versions.yml:md5,bd62c94d9b52732b89fbd979ded94a60" + [ + "HAPLOGREP3_CLASSIFY", + "haplogrep3", + "3.2.2" + ] ], "txt": [ [ @@ -58,15 +70,19 @@ "test.txt:md5,fb242df629aa6168371d1d742f0fb179" ] ], - "versions": [ - "versions.yml:md5,bd62c94d9b52732b89fbd979ded94a60" + "versions_haplogrep3": [ + [ + "HAPLOGREP3_CLASSIFY", + "haplogrep3", + "3.2.2" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-01-28T15:36:19.954363253" + "timestamp": "2025-12-08T14:14:10.117489085" } } \ No newline at end of file From 36c4abb217967eb076cde6571e3c0212f0dd57d2 Mon Sep 17 00:00:00 2001 From: "Diego Alvarez S." Date: Mon, 8 Dec 2025 12:17:51 -0300 Subject: [PATCH 26/83] semibin/singleeasybin: bump version + migrate to topics (#9517) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update semibin2 module * Update snapshot * Remove unneeded snapshot section --------- Co-authored-by: Matthias Hörtenhuber --- .../semibin/singleeasybin/environment.yml | 5 +- modules/nf-core/semibin/singleeasybin/main.nf | 37 +++---- .../nf-core/semibin/singleeasybin/meta.yml | 19 ++-- .../semibin/singleeasybin/tests/main.nf.test | 26 ++--- .../singleeasybin/tests/main.nf.test.snap | 96 ++++++++++--------- 5 files changed, 89 insertions(+), 94 deletions(-) diff --git a/modules/nf-core/semibin/singleeasybin/environment.yml b/modules/nf-core/semibin/singleeasybin/environment.yml index ae3654fbbd6d..cd1c636a4987 100644 --- a/modules/nf-core/semibin/singleeasybin/environment.yml +++ b/modules/nf-core/semibin/singleeasybin/environment.yml @@ -4,7 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::semibin=2.2.0 - # This pins solves an issue of SemiBin getting stuck. - # See https://github.com/BigDataBiology/SemiBin/issues/208 - - conda-forge::igraph=0.10.17 + - bioconda::semibin=2.2.1 diff --git a/modules/nf-core/semibin/singleeasybin/main.nf b/modules/nf-core/semibin/singleeasybin/main.nf index 913ddefa8b68..111d1fb34a05 100644 --- a/modules/nf-core/semibin/singleeasybin/main.nf +++ b/modules/nf-core/semibin/singleeasybin/main.nf @@ -1,21 +1,21 @@ process SEMIBIN_SINGLEEASYBIN { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/0d/0d205dadfeb5d37829b4fbde39319b07e2971884670ff7e84df4cc4d809ff8a5/data': - 'community.wave.seqera.io/library/semibin_igraph:fcb667d6c87bf3fd' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/2a/2aa21f74001110a50915b90b72aca51c1e2c804ce45d686e6f4085efa69f8a5b/data' + : 'community.wave.seqera.io/library/semibin:2.2.1--3214db8e39e5117b'}" input: tuple val(meta), path(fasta), path(bam) output: - tuple val(meta), path("${prefix}/*.csv") , emit: csv - tuple val(meta), path("${prefix}/*.h5") , emit: model, optional: true - tuple val(meta), path("${prefix}/*.tsv") , emit: tsv - tuple val(meta), path("${prefix}/output_bins/*.fa.gz"), emit: output_fasta - path "versions.yml", emit: versions + tuple val(meta), path("${prefix}/*.csv") , emit: csv + tuple val(meta), path("${prefix}/*.h5") , emit: model , optional: true + tuple val(meta), path("${prefix}/*.tsv") , emit: tsv + tuple val(meta), path("${prefix}/output_bins/*.fa.gz") , emit: output_fasta + tuple val("${task.process}"), val('SemiBin'), eval("SemiBin2 --version"), emit: versions_semibin, topic: versions when: task.ext.when == null || task.ext.when @@ -27,21 +27,17 @@ process SEMIBIN_SINGLEEASYBIN { """ SemiBin2 \\ - $args \\ + ${args} \\ single_easy_bin \\ --input-fasta ${fasta} \\ --input-bam ${bam} \\ --output ${prefix} \\ - -t $task.cpus \\ - $args2 - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - SemiBin: \$( SemiBin2 --version ) - END_VERSIONS + -t ${task.cpus} \\ + ${args2} """ + stub: - prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" """ mkdir ${prefix} touch ${prefix}/{contig_bins,recluster_bins_info}.tsv @@ -49,10 +45,5 @@ process SEMIBIN_SINGLEEASYBIN { mkdir ${prefix}/output_bins touch ${prefix}/output_bins/SemiBin_{0,1,2,3}.fa gzip ${prefix}/output_bins/SemiBin* - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - SemiBin: \$( SemiBin2 --version ) - END_VERSIONS """ } diff --git a/modules/nf-core/semibin/singleeasybin/meta.yml b/modules/nf-core/semibin/singleeasybin/meta.yml index 0e1f56a474b2..d60e9596aa92 100644 --- a/modules/nf-core/semibin/singleeasybin/meta.yml +++ b/modules/nf-core/semibin/singleeasybin/meta.yml @@ -76,13 +76,18 @@ output: description: precluster fasta files pattern: "*.fa" ontologies: [] - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML + versions_semibin: &versions + - - ${task.process}: + type: string + description: The name of the process + - SemiBin: + type: string + description: The name of the tool + - "SemiBin2 --version": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: *versions authors: - "@BigDataBiology" maintainers: diff --git a/modules/nf-core/semibin/singleeasybin/tests/main.nf.test b/modules/nf-core/semibin/singleeasybin/tests/main.nf.test index 142e13fa512b..30fa044c7328 100644 --- a/modules/nf-core/semibin/singleeasybin/tests/main.nf.test +++ b/modules/nf-core/semibin/singleeasybin/tests/main.nf.test @@ -21,20 +21,17 @@ nextflow_process { process { """ input[0] = [ - [id:'test'], - file(params.modules_testdata_base_path + 'genomics/prokaryotes/bacteroides_fragilis/illumina/fasta/test1.contigs.fa.gz', checkIfExists:true), - file(params.modules_testdata_base_path + 'genomics/prokaryotes/bacteroides_fragilis/illumina/bam/test1_contigs.sorted.bam', checkIfExists:true) - ] + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/prokaryotes/bacteroides_fragilis/illumina/fasta/test1.contigs.fa.gz', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/prokaryotes/bacteroides_fragilis/illumina/bam/test1_contigs.sorted.bam', checkIfExists:true) + ] """ } } then { assert process.success assertAll( - { assert snapshot( - process.out, - path(process.out.versions[0]).yaml - ).match() } + { assert snapshot(process.out).match() } ) } } @@ -49,20 +46,17 @@ nextflow_process { process { """ input[0] = [ - [id:'test'], - file(params.modules_testdata_base_path + 'genomics/prokaryotes/bacteroides_fragilis/illumina/fasta/test1.contigs.fa.gz', checkIfExists:true), - file(params.modules_testdata_base_path + 'genomics/prokaryotes/bacteroides_fragilis/illumina/bam/test1_contigs.sorted.bam', checkIfExists:true) - ] + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/prokaryotes/bacteroides_fragilis/illumina/fasta/test1.contigs.fa.gz', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/prokaryotes/bacteroides_fragilis/illumina/bam/test1_contigs.sorted.bam', checkIfExists:true) + ] """ } } then { assert process.success assertAll( - { assert snapshot( - process.out, - path(process.out.versions[0]).yaml - ).match() } + { assert snapshot(process.out).match() } ) } } diff --git a/modules/nf-core/semibin/singleeasybin/tests/main.nf.test.snap b/modules/nf-core/semibin/singleeasybin/tests/main.nf.test.snap index affadd0ef7bc..0a8d214a8dd2 100644 --- a/modules/nf-core/semibin/singleeasybin/tests/main.nf.test.snap +++ b/modules/nf-core/semibin/singleeasybin/tests/main.nf.test.snap @@ -23,8 +23,8 @@ "id": "test" }, [ - "contig_bins.tsv:md5,916794264bed0eefb53ec751c19862f0", - "recluster_bins_info.tsv:md5,271b128eac7a71a1fc95efddf07e1e3d" + "contig_bins.tsv:md5,4ca344a6afd99ec00b364998e88f8860", + "recluster_bins_info.tsv:md5,18975f1d33e4d060eae440ccf88a339b" ] ] ], @@ -34,8 +34,8 @@ "id": "test" }, [ - "SemiBin_0.fa.gz:md5,87086957c6c48e2c7c8487e8f46153d3", - "SemiBin_1.fa.gz:md5,fbeaa0f639121a85115bc3c901be3cfe", + "SemiBin_0.fa.gz:md5,d03dbf09afa367f26b76c7cf8506a471", + "SemiBin_1.fa.gz:md5,f44ce9c34e8ed8743e82c9597dfa4d7c", "SemiBin_10.fa.gz:md5,26d8fb83db377abef7d62d291d6dedc4", "SemiBin_11.fa.gz:md5,caaec1412eabe5bc7099f7fe883e7998", "SemiBin_12.fa.gz:md5,55b5482682aec7baa33c0646569f82b1", @@ -52,21 +52,26 @@ "SemiBin_22.fa.gz:md5,c98a8752771d62d966a88fec80edc4c2", "SemiBin_23.fa.gz:md5,c9ab00537eee994d2ad326998ddd559d", "SemiBin_24.fa.gz:md5,039495af6b66f05d415e7de7fe0a20fb", - "SemiBin_25.fa.gz:md5,9a204ce83ea1fa70934cd0dc78953a02", - "SemiBin_26.fa.gz:md5,63750434b3295487ea7c3f747347ea18", - "SemiBin_27.fa.gz:md5,00e61d0c6a894debb626d97a7a468163", + "SemiBin_25.fa.gz:md5,679d9fbca921a242fa36c4eb58439d17", + "SemiBin_26.fa.gz:md5,9a204ce83ea1fa70934cd0dc78953a02", + "SemiBin_27.fa.gz:md5,63750434b3295487ea7c3f747347ea18", + "SemiBin_28.fa.gz:md5,00e61d0c6a894debb626d97a7a468163", "SemiBin_3.fa.gz:md5,4730f1e32e5323283fe885884f10699e", - "SemiBin_4.fa.gz:md5,d94e4065dfb334eb34f04f4f06af648e", - "SemiBin_5.fa.gz:md5,27ad83d85184527847a2cc13b1c990b0", - "SemiBin_6.fa.gz:md5,1741f7cac38fb8c5b03600ec2fe027c0", - "SemiBin_7.fa.gz:md5,406697b0e472cf577b6b265466ab73af", - "SemiBin_8.fa.gz:md5,b9ce47f44ef95492c7cb1a578ad48b7d", + "SemiBin_4.fa.gz:md5,546de9f41e32277068eb27a18eb5455c", + "SemiBin_5.fa.gz:md5,d94e4065dfb334eb34f04f4f06af648e", + "SemiBin_6.fa.gz:md5,27ad83d85184527847a2cc13b1c990b0", + "SemiBin_7.fa.gz:md5,1741f7cac38fb8c5b03600ec2fe027c0", + "SemiBin_8.fa.gz:md5,406697b0e472cf577b6b265466ab73af", "SemiBin_9.fa.gz:md5,f1c9b082977bf100918591b489fd03e2" ] ] ], "4": [ - "versions.yml:md5,cbc3652f97526cada170758d03959d6f" + [ + "SEMIBIN_SINGLEEASYBIN", + "SemiBin", + "2.2.1" + ] ], "csv": [ [ @@ -89,8 +94,8 @@ "id": "test" }, [ - "SemiBin_0.fa.gz:md5,87086957c6c48e2c7c8487e8f46153d3", - "SemiBin_1.fa.gz:md5,fbeaa0f639121a85115bc3c901be3cfe", + "SemiBin_0.fa.gz:md5,d03dbf09afa367f26b76c7cf8506a471", + "SemiBin_1.fa.gz:md5,f44ce9c34e8ed8743e82c9597dfa4d7c", "SemiBin_10.fa.gz:md5,26d8fb83db377abef7d62d291d6dedc4", "SemiBin_11.fa.gz:md5,caaec1412eabe5bc7099f7fe883e7998", "SemiBin_12.fa.gz:md5,55b5482682aec7baa33c0646569f82b1", @@ -107,15 +112,16 @@ "SemiBin_22.fa.gz:md5,c98a8752771d62d966a88fec80edc4c2", "SemiBin_23.fa.gz:md5,c9ab00537eee994d2ad326998ddd559d", "SemiBin_24.fa.gz:md5,039495af6b66f05d415e7de7fe0a20fb", - "SemiBin_25.fa.gz:md5,9a204ce83ea1fa70934cd0dc78953a02", - "SemiBin_26.fa.gz:md5,63750434b3295487ea7c3f747347ea18", - "SemiBin_27.fa.gz:md5,00e61d0c6a894debb626d97a7a468163", + "SemiBin_25.fa.gz:md5,679d9fbca921a242fa36c4eb58439d17", + "SemiBin_26.fa.gz:md5,9a204ce83ea1fa70934cd0dc78953a02", + "SemiBin_27.fa.gz:md5,63750434b3295487ea7c3f747347ea18", + "SemiBin_28.fa.gz:md5,00e61d0c6a894debb626d97a7a468163", "SemiBin_3.fa.gz:md5,4730f1e32e5323283fe885884f10699e", - "SemiBin_4.fa.gz:md5,d94e4065dfb334eb34f04f4f06af648e", - "SemiBin_5.fa.gz:md5,27ad83d85184527847a2cc13b1c990b0", - "SemiBin_6.fa.gz:md5,1741f7cac38fb8c5b03600ec2fe027c0", - "SemiBin_7.fa.gz:md5,406697b0e472cf577b6b265466ab73af", - "SemiBin_8.fa.gz:md5,b9ce47f44ef95492c7cb1a578ad48b7d", + "SemiBin_4.fa.gz:md5,546de9f41e32277068eb27a18eb5455c", + "SemiBin_5.fa.gz:md5,d94e4065dfb334eb34f04f4f06af648e", + "SemiBin_6.fa.gz:md5,27ad83d85184527847a2cc13b1c990b0", + "SemiBin_7.fa.gz:md5,1741f7cac38fb8c5b03600ec2fe027c0", + "SemiBin_8.fa.gz:md5,406697b0e472cf577b6b265466ab73af", "SemiBin_9.fa.gz:md5,f1c9b082977bf100918591b489fd03e2" ] ] @@ -126,26 +132,25 @@ "id": "test" }, [ - "contig_bins.tsv:md5,916794264bed0eefb53ec751c19862f0", - "recluster_bins_info.tsv:md5,271b128eac7a71a1fc95efddf07e1e3d" + "contig_bins.tsv:md5,4ca344a6afd99ec00b364998e88f8860", + "recluster_bins_info.tsv:md5,18975f1d33e4d060eae440ccf88a339b" ] ] ], - "versions": [ - "versions.yml:md5,cbc3652f97526cada170758d03959d6f" + "versions_semibin": [ + [ + "SEMIBIN_SINGLEEASYBIN", + "SemiBin", + "2.2.1" + ] ] - }, - { - "SEMIBIN_SINGLEEASYBIN": { - "SemiBin": "2.2.0" - } } ], "meta": { "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-02T13:19:13.461592294" + "timestamp": "2025-12-08T12:07:46.964893039" }, "bacteroides_fragilis - stub": { "content": [ @@ -189,7 +194,11 @@ ] ], "4": [ - "versions.yml:md5,cbc3652f97526cada170758d03959d6f" + [ + "SEMIBIN_SINGLEEASYBIN", + "SemiBin", + "2.2.1" + ] ], "csv": [ [ @@ -229,20 +238,19 @@ ] ] ], - "versions": [ - "versions.yml:md5,cbc3652f97526cada170758d03959d6f" + "versions_semibin": [ + [ + "SEMIBIN_SINGLEEASYBIN", + "SemiBin", + "2.2.1" + ] ] - }, - { - "SEMIBIN_SINGLEEASYBIN": { - "SemiBin": "2.2.0" - } } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.6" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-05-09T08:28:29.291321203" + "timestamp": "2025-12-08T12:08:04.255646853" } } \ No newline at end of file From 9239334eacd1f332c8cf9f92a9a47180288955fc Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Mon, 8 Dec 2025 17:01:42 +0000 Subject: [PATCH 27/83] remove unused folder --- setup-nextflow | 1 - 1 file changed, 1 deletion(-) delete mode 160000 setup-nextflow diff --git a/setup-nextflow b/setup-nextflow deleted file mode 160000 index 6c2e22b4d901..000000000000 --- a/setup-nextflow +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6c2e22b4d901f0c42ca66c5069f8026df026d165 From ced42709317e396d96dfcb88781e2894f8b434ec Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Mon, 8 Dec 2025 17:07:45 +0000 Subject: [PATCH 28/83] rename --- .../main.nf | 22 +++++++++---------- .../meta.yml | 2 +- .../tests/main.nf.test | 4 ++-- .../tests/main.nf.test.snap | 0 .../tests/nextflow.config | 5 +++-- 5 files changed, 17 insertions(+), 16 deletions(-) rename subworkflows/nf-core/{fastq_remove_adapters_and_merge => fastq_removeadapters_merge}/main.nf (93%) rename subworkflows/nf-core/{fastq_remove_adapters_and_merge => fastq_removeadapters_merge}/meta.yml (97%) rename subworkflows/nf-core/{fastq_remove_adapters_and_merge => fastq_removeadapters_merge}/tests/main.nf.test (96%) rename subworkflows/nf-core/{fastq_remove_adapters_and_merge => fastq_removeadapters_merge}/tests/main.nf.test.snap (100%) rename subworkflows/nf-core/{fastq_remove_adapters_and_merge => fastq_removeadapters_merge}/tests/nextflow.config (98%) diff --git a/subworkflows/nf-core/fastq_remove_adapters_and_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf similarity index 93% rename from subworkflows/nf-core/fastq_remove_adapters_and_merge/main.nf rename to subworkflows/nf-core/fastq_removeadapters_merge/main.nf index f13df3bef4af..2f522fa6c89e 100644 --- a/subworkflows/nf-core/fastq_remove_adapters_and_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -12,7 +12,7 @@ include { LEEHOM } from '../../../modules/nf-core/leehom/main' // requirs paired end becouse of merging include { NGMERGE } from '../../../modules/nf-core/ngmerge/main' -workflow FASTQ_REMOVE_ADAPTERS_AND_MERGE { +workflow FASTQ_REMOVEADAPTERS_MERGE { take: reads // (meta, reads) - SE or PE @@ -24,7 +24,7 @@ workflow FASTQ_REMOVE_ADAPTERS_AND_MERGE { skip_adapterremoval skip_leehom skip_ngmerge - do_merge + do_merge adapters_contaminants main: @@ -61,25 +61,25 @@ workflow FASTQ_REMOVE_ADAPTERS_AND_MERGE { if (!skip_fastp && !do_merge) { ch_current.view { "DEBUG: BEFORE FASTP → $it" } FASTP( ch_current.map { meta, r -> tuple(meta, r, adapters_contaminants)}, - false, - true, - do_merge) + false, + true, + do_merge) ch_current = FASTP.out.reads.map { meta, r -> [meta, r] } ch_versions = ch_versions.mix(FASTP.out.versions) ch_current.view { "DEBUG: AFTER FASTP → $it" } } - if (!skip_adapterremoval && !do_merge) { - ADAPTERREMOVAL( ch_current, adapters_contaminants ) + if (!skip_adapterremoval && !do_merge) { + ADAPTERREMOVAL( ch_current, adapters_contaminants ) ch_current.view { "DEBUG: BEFORE ADAPTERREMOVAL → $it" } ch_current = ADAPTERREMOVAL.out.paired_truncated .mix(ADAPTERREMOVAL.out.singles_truncated) .map { tup -> def meta = tup[0] - def r = tup[1] + def r = tup[1] [meta, r] - } - ch_versions = ch_versions.mix(ADAPTERREMOVAL.out.versions) + } + ch_versions = ch_versions.mix(ADAPTERREMOVAL.out.versions) ch_current.view { "DEBUG: AFTER ADAPTERREMOVAL → $it" } } @@ -118,7 +118,7 @@ ch_current = ch_leehom_pe.mix(ch_leehom_se) } emit: - + trimmed_reads = ch_current // channel: [ meta, trimmed_reads ] versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/fastq_remove_adapters_and_merge/meta.yml b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml similarity index 97% rename from subworkflows/nf-core/fastq_remove_adapters_and_merge/meta.yml rename to subworkflows/nf-core/fastq_removeadapters_merge/meta.yml index 0390e17f75c6..514fac8f7cd2 100644 --- a/subworkflows/nf-core/fastq_remove_adapters_and_merge/meta.yml +++ b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml @@ -1,5 +1,5 @@ # yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json -name: "fastq_remove_adapters_and_merge" +name: "fastq_removeadapters_merge" ## TODO nf-core: Add a description of the subworkflow and list keywords description: Sort SAM/BAM/CRAM file keywords: diff --git a/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test similarity index 96% rename from subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test rename to subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index 3ba4c0236b64..8fa394ddb4ef 100644 --- a/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -1,8 +1,8 @@ nextflow_workflow { - name "Test Subworkflow FASTQ_REMOVE_ADAPTERS_AND_MERGE" + name "Test Subworkflow FASTQ_REMOVEADAPTERS_MERGE" script "../main.nf" - workflow "FASTQ_REMOVE_ADAPTERS_AND_MERGE" + workflow "FASTQ_REMOVEADAPTERS_MERGE" tag "subworkflows" tag "trimmomatic" diff --git a/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap similarity index 100% rename from subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/main.nf.test.snap rename to subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap diff --git a/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/nextflow.config b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config similarity index 98% rename from subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/nextflow.config rename to subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config index 6b7b780d8765..6caa491600e7 100644 --- a/subworkflows/nf-core/fastq_remove_adapters_and_merge/tests/nextflow.config +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config @@ -1,5 +1,4 @@ process { - withName: TRIMMOMATIC { ext.args = { def adapters = "TruSeq3-SE.fa" @@ -10,8 +9,10 @@ process { withName: CUTADAPT { ext.args = '-q 25' } + withName: BBMAP_BBDUK { ext.args = 'trimq=10 qtrim=r' ext.prefix = { "${meta.id}.trim" } } - } + +} From a68276ab5d0ae79c46da139de3dcd93f82dbd16c Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Mon, 8 Dec 2025 18:02:23 +0000 Subject: [PATCH 29/83] trimmomatic revisit --- .../fastq_removeadapters_merge/main.nf | 229 +++++++++--------- .../fastq_removeadapters_merge/meta.yml | 64 ++--- .../tests/main.nf.test | 131 ++++++---- .../tests/main.nf.test.snap | 99 +++----- .../tests/nextflow.config | 21 +- .../tests/nextflow_PE.config | 6 + .../tests/nextflow_SE.config | 6 + 7 files changed, 285 insertions(+), 271 deletions(-) create mode 100644 subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_PE.config create mode 100644 subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_SE.config diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index 2f522fa6c89e..61e51ebebe03 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -1,124 +1,133 @@ // ok for single end adapter removal -include { TRIMMOMATIC } from '../../../modules/nf-core/trimmomatic/main' -include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' -include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' -include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' - -// allows merging of paired end reads, but will work for single end reads as well -include { FASTP } from '../../../modules/nf-core/fastp/main' -include { ADAPTERREMOVAL} from '../../../modules/nf-core/adapterremoval/main' -include { LEEHOM } from '../../../modules/nf-core/leehom/main' - -// requirs paired end becouse of merging -include { NGMERGE } from '../../../modules/nf-core/ngmerge/main' +include { TRIMMOMATIC } from '../../../modules/nf-core/trimmomatic/main' // both SE and PE +// include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' +// include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' +// include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' +// // allows merging of paired end reads, but will work for single end reads as well +// include { FASTP } from '../../../modules/nf-core/fastp/main' +// include { ADAPTERREMOVAL} from '../../../modules/nf-core/adapterremoval/main' +// include { LEEHOM } from '../../../modules/nf-core/leehom/main' +// // requires paired end because of merging +// include { NGMERGE } from '../../../modules/nf-core/ngmerge/main' workflow FASTQ_REMOVEADAPTERS_MERGE { take: - reads // (meta, reads) - SE or PE - skip_trimmomatic // boolean - skip_cutadapt - skip_trimgalore - skip_bbduk - skip_fastp - skip_adapterremoval - skip_leehom - skip_ngmerge - do_merge - adapters_contaminants + reads // channel: [ val(meta), [ reads ] ] + skip_trimmomatic // boolean + // skip_cutadapt // boolean + // skip_trimgalore // boolean + // skip_bbduk // boolean + // skip_fastp // boolean + // skip_adapterremoval // boolean + // skip_leehom // boolean + // skip_ngmerge // boolean + // do_merge + // adapters_contaminants + main: - ch_current = reads - ch_versions = Channel.empty() + ch_reads = reads + ch_trimmomatic_unpaired_reads = channel.empty() + ch_trimmomatic_trim_log = channel.empty() + ch_trimmomatic_out_log = channel.empty() + ch_trimmomatic_summary = channel.empty() + ch_versions = channel.empty() if (!skip_trimmomatic) { - // TRIMMOMATIC.ext.adapters = adapters_contaminants - TRIMMOMATIC( ch_current ) - ch_current = TRIMMOMATIC.out.trimmed_reads.map { meta, r -> [meta, r] } - ch_versions = ch_versions.mix(TRIMMOMATIC.out.versions) - } - - if (!skip_cutadapt) { - CUTADAPT( ch_current ) - ch_current = CUTADAPT.out.reads.map { meta, r -> [meta, r] } - ch_versions = ch_versions.mix(CUTADAPT.out.versions) - } - - if (!skip_trimgalore) { - TRIMGALORE( ch_current ) - ch_current = TRIMGALORE.out.reads.map { meta, r -> [meta, r] } - ch_versions = ch_versions.mix(TRIMGALORE.out.versions) - } - - if (!skip_bbduk) { - ch_current.view { "DEBUG: BEFORE BBMAP_BBDUK → $it" } - BBMAP_BBDUK( ch_current, adapters_contaminants ) - ch_current = BBMAP_BBDUK.out.reads.map { meta, r -> [meta, r] } - ch_versions = ch_versions.mix(BBMAP_BBDUK.out.versions) - ch_current.view { "DEBUG: AFTER BBMAP_BBDUK → $it" } + TRIMMOMATIC( ch_reads ) + ch_reads = TRIMMOMATIC.out.trimmed_reads // .map { meta, r -> [meta, r] } // TODO remove probably + ch_trimmomatic_unpaired_reads = TRIMMOMATIC.out.unpaired_reads + ch_trimmomatic_trim_log = TRIMMOMATIC.out.trim_log + ch_trimmomatic_out_log = TRIMMOMATIC.out.out_log + ch_trimmomatic_summary = TRIMMOMATIC.out.summary + ch_versions = ch_versions.mix(TRIMMOMATIC.out.versions) } - if (!skip_fastp && !do_merge) { - ch_current.view { "DEBUG: BEFORE FASTP → $it" } - FASTP( ch_current.map { meta, r -> tuple(meta, r, adapters_contaminants)}, - false, - true, - do_merge) - ch_current = FASTP.out.reads.map { meta, r -> [meta, r] } - ch_versions = ch_versions.mix(FASTP.out.versions) - ch_current.view { "DEBUG: AFTER FASTP → $it" } - } - - if (!skip_adapterremoval && !do_merge) { - ADAPTERREMOVAL( ch_current, adapters_contaminants ) - ch_current.view { "DEBUG: BEFORE ADAPTERREMOVAL → $it" } - ch_current = ADAPTERREMOVAL.out.paired_truncated - .mix(ADAPTERREMOVAL.out.singles_truncated) - .map { tup -> - def meta = tup[0] - def r = tup[1] - [meta, r] - } - ch_versions = ch_versions.mix(ADAPTERREMOVAL.out.versions) - ch_current.view { "DEBUG: AFTER ADAPTERREMOVAL → $it" } - } - - if (!skip_leehom && !do_merge) { - ch_current.view { "DEBUG: BEFORE LEEHOM → $it" } - ch_leehom_input = ch_current.map { meta, r -> - if (meta.single_end) - return [meta, r] - else - return [meta, [reads[0], reads[1]]] - } - - LEEHOM(ch_leehom_input) - - ch_leehom_pe = - LEEHOM.out.unmerged_r1_fq_pass - .combine(LEEHOM.out.unmerged_r2_fq_pass) - .map { left, right -> - def meta = left[0] - def r1 = left[1] - def r2 = right[1] - [meta, [r1, r2]] - } - .filter { meta, r -> !meta.single_end } // only PE - -// ---- SE OUTPUT ---- -ch_leehom_se = - LEEHOM.out.fq_pass - .filter { meta, r -> meta.single_end } - .map { meta, r -> [meta, r] } - -// ---- MERGE CHANNELS ---- -ch_current = ch_leehom_pe.mix(ch_leehom_se) - - ch_versions = ch_versions.mix(LEEHOM.out.versions) - } +// if (!skip_cutadapt) { +// CUTADAPT( ch_reads ) +// ch_reads = CUTADAPT.out.reads.map { meta, r -> [meta, r] } +// ch_versions = ch_versions.mix(CUTADAPT.out.versions) +// } + +// if (!skip_trimgalore) { +// TRIMGALORE( ch_reads ) +// ch_reads = TRIMGALORE.out.reads.map { meta, r -> [meta, r] } +// ch_versions = ch_versions.mix(TRIMGALORE.out.versions) +// } + +// if (!skip_bbduk) { +// ch_reads.view { "DEBUG: BEFORE BBMAP_BBDUK → $it" } +// BBMAP_BBDUK( ch_reads, adapters_contaminants ) +// ch_reads = BBMAP_BBDUK.out.reads.map { meta, r -> [meta, r] } +// ch_versions = ch_versions.mix(BBMAP_BBDUK.out.versions) +// ch_reads.view { "DEBUG: AFTER BBMAP_BBDUK → $it" } +// } + +// if (!skip_fastp && !do_merge) { +// ch_reads.view { "DEBUG: BEFORE FASTP → $it" } +// FASTP( ch_reads.map { meta, r -> tuple(meta, r, adapters_contaminants)}, +// false, +// true, +// do_merge) +// ch_reads = FASTP.out.reads.map { meta, r -> [meta, r] } +// ch_versions = ch_versions.mix(FASTP.out.versions) +// ch_reads.view { "DEBUG: AFTER FASTP → $it" } +// } + +// if (!skip_adapterremoval && !do_merge) { +// ADAPTERREMOVAL( ch_reads, adapters_contaminants ) +// ch_reads.view { "DEBUG: BEFORE ADAPTERREMOVAL → $it" } +// ch_reads = ADAPTERREMOVAL.out.paired_truncated +// .mix(ADAPTERREMOVAL.out.singles_truncated) +// .map { tup -> +// def meta = tup[0] +// def r = tup[1] +// [meta, r] +// } +// ch_versions = ch_versions.mix(ADAPTERREMOVAL.out.versions) +// ch_reads.view { "DEBUG: AFTER ADAPTERREMOVAL → $it" } +// } + +// if (!skip_leehom && !do_merge) { +// ch_reads.view { "DEBUG: BEFORE LEEHOM → $it" } +// ch_leehom_input = ch_reads.map { meta, r -> +// if (meta.single_end) +// return [meta, r] +// else +// return [meta, [reads[0], reads[1]]] +// } + +// LEEHOM(ch_leehom_input) + +// ch_leehom_pe = +// LEEHOM.out.unmerged_r1_fq_pass +// .combine(LEEHOM.out.unmerged_r2_fq_pass) +// .map { left, right -> +// def meta = left[0] +// def r1 = left[1] +// def r2 = right[1] +// [meta, [r1, r2]] +// } +// .filter { meta, r -> !meta.single_end } // only PE + +// // ---- SE OUTPUT ---- +// ch_leehom_se = +// LEEHOM.out.fq_pass +// .filter { meta, r -> meta.single_end } +// .map { meta, r -> [meta, r] } + +// // ---- MERGE CHANNELS ---- +// ch_reads = ch_leehom_pe.mix(ch_leehom_se) + +// ch_versions = ch_versions.mix(LEEHOM.out.versions) +// } emit: - - trimmed_reads = ch_current // channel: [ meta, trimmed_reads ] - versions = ch_versions // channel: [ versions.yml ] + reads = ch_reads // channel: [ val(meta), [ fastq.gz ] ] + trimmomatic_unpaired_reads = ch_trimmomatic_unpaired_reads // channel: [ val(meta), [ fastq.gz ] ] + trimmomatic_trim_log = ch_trimmomatic_trim_log // channel: [ val(meta), [ log ] ] + trimmomatic_out_log = ch_trimmomatic_out_log // channel: [ val(meta), [ log ] ] + trimmomatic_summary = ch_trimmomatic_summary // channel: [ val(meta), [ summary ] ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml index 514fac8f7cd2..3ab05df2e8d7 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml +++ b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml @@ -1,44 +1,46 @@ # yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json name: "fastq_removeadapters_merge" -## TODO nf-core: Add a description of the subworkflow and list keywords -description: Sort SAM/BAM/CRAM file +description: Remove adapters and merge reads based on various module choices keywords: - - sort - - bam - - sam - - cram -## TODO nf-core: Add a list of the modules and/or subworkflows used in the subworkflow + - adapters + - removal + - short reads + - merge + - trim + - trimmomatic components: - - samtools/sort - - samtools/index -## TODO nf-core: List all of the channels used as input with a description and their structure + - trimmomatic input: - - ch_bam: + - ch_reads: type: file description: | - The input channel containing the BAM/CRAM/SAM files - Structure: [ val(meta), path(bam) ] - pattern: "*.{bam/cram/sam}" -## TODO nf-core: List all of the channels used as output with a descriptions and their structure + List of FastQ files of size 1 and 2 for single-end and paired-end data, respectively. + Structure: [ val(meta), [ path(reads) ] ] + - skip_trimmomatic: + type: boolean + description: | + If true, skips the trimmomatic process. output: - - bam: + - reads: type: file - description: | - Channel containing BAM files - Structure: [ val(meta), path(bam) ] - pattern: "*.bam" - - bai: + description: The trimmed/modified single or paired end fastq reads + pattern: "*.fastq.gz" + - trimmomatic_unpaired_reads: type: file - description: | - Channel containing indexed BAM (BAI) files - Structure: [ val(meta), path(bai) ] - pattern: "*.bai" - - csi: + description: The trimmed/modified unpaired end fastq reads + pattern: "*.unpaired.trim_*.fastq.gz" + - trimmomatic_trim_log: type: file - description: | - Channel containing CSI files - Structure: [ val(meta), path(csi) ] - pattern: "*.csi" + description: trimmomatic log file, from the trim_log parameter + pattern: "*.log" + - trimmomatic_out_log: + type: file + description: log of output from the standard out + pattern: "*.log" + - trimmomatic_summary: + type: file + description: trimmomatic summary file of surviving and dropped reads + pattern: "*.summary" - versions: type: file description: | @@ -47,5 +49,7 @@ output: pattern: "versions.yml" authors: - "@kornkv" + - "@vagkaratzas" maintainers: - "@kornkv" + - "@vagkaratzas" diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index 8fa394ddb4ef..caec48f20652 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -3,22 +3,23 @@ nextflow_workflow { name "Test Subworkflow FASTQ_REMOVEADAPTERS_MERGE" script "../main.nf" workflow "FASTQ_REMOVEADAPTERS_MERGE" + // config './nextflow.config' tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/fastq_removeadapters_merge" tag "trimmomatic" - tag "cutadapt" - tag "trimgalore" - tag "bbmap/bbduk" - tag "fastp" - tag "adapterremoval" - tag "leehom" - tag "ngmerge" + // tag "cutadapt" + // tag "trimgalore" + // tag "bbmap" + // tag "bbmap/bbduk" + // tag "fastp" + // tag "adapterremoval" + // tag "leehom" + // tag "ngmerge" - /************************************************************** - * TEST 1 — SINGLE END - **************************************************************/ test("sarscov2 - fastq - single-end") { - config "./nextflow.config" + config "./nextflow_SE.config" when { workflow { """ @@ -28,42 +29,39 @@ nextflow_workflow { ] input[1] = false // skip_trimmomatic - input[2] = false // skip_cutadapt - input[3] = false // skip_trimgalore - input[4] = false // skip_bbduk - input[5] = false // skip_fastp - input[6] = false // skip_adapterremoval - input[7] = false // skip_leehom - input[8] = true // skip_ngmerge - input[9] = false // do_merge - input[10] = [] + // input[2] = false // skip_cutadapt + // input[3] = false // skip_trimgalore + // input[4] = false // skip_bbduk + // input[5] = false // skip_fastp + // input[6] = false // skip_adapterremoval + // input[7] = false // skip_leehom + // input[8] = true // skip_ngmerge + // input[9] = false // do_merge + // input[10] = [] """ } } then { assert workflow.success - assert snapshot( - workflow.out.trimmed_reads.sort(), - workflow.out.versions.collect { path(it).yaml }.sort() + workflow.out.reads[0][1], + // workflow.out.trimmomatic_unpaired_reads[0][1], + workflow.out.trimmomatic_trim_log[0][1], + file(workflow.out.trimmomatic_out_log[0][1]).name, + workflow.out.trimmomatic_summary[0][1], + workflow.out.versions.collect { path(it).yaml } ).match() } } - - /************************************************************** - * TEST 2 — PAIRED END - **************************************************************/ - test("sarscov2 - fastq - paired-end, no merging") { - config "./nextflow.config" - when { params { - samtools_arg = '' - } + test("sarscov2 - fastq - paired-end") { + config "./nextflow_PE.config" + when { workflow { """ input[0] = [ - [ id:'test_paired', single_end:false ], + [ id:'test', single_end:false ], [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) @@ -71,25 +69,66 @@ nextflow_workflow { ] input[1] = false // skip_trimmomatic - input[2] = false // skip_cutadapt - input[3] = false // skip_trimgalore - input[4] = false // skip_bbduk - input[5] = false // skip_fastp - input[6] = false // skip_adapterremoval - input[7] = false // skip_leehom - input[8] = true // skip_ngmerge - input[9] = false // do_merge - input[10] = [] + // input[2] = false // skip_cutadapt + // input[3] = false // skip_trimgalore + // input[4] = false // skip_bbduk + // input[5] = false // skip_fastp + // input[6] = false // skip_adapterremoval + // input[7] = false // skip_leehom + // input[8] = true // skip_ngmerge + // input[9] = false // do_merge + // input[10] = [] """ } } then { - assertAll( - { assert workflow.success }, - { assert snapshot(workflow.out).match() } - ) + assert workflow.success + assert snapshot( + workflow.out.reads[0][1], + workflow.out.trimmomatic_unpaired_reads[0][1], + workflow.out.trimmomatic_trim_log[0][1], + file(workflow.out.trimmomatic_out_log[0][1]).name, + workflow.out.trimmomatic_summary[0][1], + workflow.out.versions.collect { path(it).yaml } + ).match() } } + // test("sarscov2 - fastq - paired-end, no merging") { + // when { params { + // samtools_arg = '' + // } + // workflow { + // """ + // input[0] = [ + // [ id:'test_paired', single_end:false ], + // [ + // file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + // file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + // ] + // ] + + // input[1] = false // skip_trimmomatic + // input[2] = false // skip_cutadapt + // input[3] = false // skip_trimgalore + // input[4] = false // skip_bbduk + // input[5] = false // skip_fastp + // input[6] = false // skip_adapterremoval + // input[7] = false // skip_leehom + // input[8] = true // skip_ngmerge + // input[9] = false // do_merge + // input[10] = [] + // """ + // } + // } + + // then { + // assertAll( + // { assert workflow.success }, + // { assert snapshot(workflow.out).match() } + // ) + // } + // } + } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap index d66a72a5622e..54740e44c99c 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap @@ -1,92 +1,49 @@ { - "sarscov2 - fastq - paired-end, no merging": { + "sarscov2 - fastq - paired-end": { "content": [ - { - "0": [ - - ], - "1": [ - "versions.yml:md5,2d964cf60309a142f1c9958da875eb54", - "versions.yml:md5,90401b38cbb7e43510ca1a7cbcea3145", - "versions.yml:md5,95732be10dd312717626b93c727886ef", - "versions.yml:md5,aa5ed9a565951378f5d671bfa6b88370", - "versions.yml:md5,b9c8e5d6936d4d2dbc08084d03ee57c8", - "versions.yml:md5,de9c9c39a848b9543456f693e4ca6ad3" - ], - "trimmed_reads": [ - - ], - "versions": [ - "versions.yml:md5,2d964cf60309a142f1c9958da875eb54", - "versions.yml:md5,90401b38cbb7e43510ca1a7cbcea3145", - "versions.yml:md5,95732be10dd312717626b93c727886ef", - "versions.yml:md5,aa5ed9a565951378f5d671bfa6b88370", - "versions.yml:md5,b9c8e5d6936d4d2dbc08084d03ee57c8", - "versions.yml:md5,de9c9c39a848b9543456f693e4ca6ad3" - ] - } + [ + "test.paired.trim_1.fastq.gz:md5,a866e64f451745f176316d0df7d52b30", + "test.paired.trim_2.fastq.gz:md5,725d4ab909b39291ab56b090cab32075" + ], + [ + "test.unpaired.trim_1.fastq.gz:md5,f22935d14248bd936af8d5e3c27e72b2", + "test.unpaired.trim_2.fastq.gz:md5,ce0d8e849e4677a186cd0566b2a6ea15" + ], + "test_trim.log:md5,9629761761a34576b3484bf4174f681f", + "test_out.log", + "test.summary:md5,9698e5e5c060bbe64588998fe35f8d71", + [ + { + "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { + "trimmomatic": 0.39 + } + } + ] ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T10:34:07.314632994" + "timestamp": "2025-12-08T17:49:41.579082238" }, "sarscov2 - fastq - single-end": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.fq.gz:md5,6dcea64429b2bcf5e31751f9c8041914" - ] - ], + "test.SE.paired.trim.fastq.gz:md5,e68abbd3b88f7ec12940a4f5c2b8bfb9", + "test_trim.log:md5,e4c3f619e9b0e26847f8f3e3d9af319b", + "test_out.log", + "test.summary:md5,24c973237557a1439c775ca19a5deaa5", [ { - "FASTQ_REMOVE_ADAPTERS_AND_MERGE:FASTP": { - "fastp": "1.0.1" - } - }, - { - "FASTQ_REMOVE_ADAPTERS_AND_MERGE:TRIMGALORE": { - "trimgalore": "0.6.10", - "cutadapt": 4.9, - "pigz": 2.8 - } - }, - { - "FASTQ_REMOVE_ADAPTERS_AND_MERGE:LEEHOM": { - "leehom": "1.2.15" - } - }, - { - "FASTQ_REMOVE_ADAPTERS_AND_MERGE:ADAPTERREMOVAL": { - "adapterremoval": "2.3.2" - } - }, - { - "FASTQ_REMOVE_ADAPTERS_AND_MERGE:TRIMMOMATIC": { + "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { "trimmomatic": 0.39 } - }, - { - "FASTQ_REMOVE_ADAPTERS_AND_MERGE:BBMAP_BBDUK": { - "bbmap": 39.18 - } - }, - { - "FASTQ_REMOVE_ADAPTERS_AND_MERGE:CUTADAPT": { - "cutadapt": 5.0 - } } ] ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T10:33:53.838298621" + "timestamp": "2025-12-08T17:48:51.793945465" } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config index 6caa491600e7..0e9f544cd2a1 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config @@ -1,18 +1,11 @@ process { - withName: TRIMMOMATIC { - ext.args = { - def adapters = "TruSeq3-SE.fa" - "ILLUMINACLIP:${adapters}:2:30:10 LEADING:3 TRAILING:3 SLIDINGWINDOW:4:15 MINLEN:36" - } - } + // withName: CUTADAPT { + // ext.args = '-q 25' + // } - withName: CUTADAPT { - ext.args = '-q 25' - } - - withName: BBMAP_BBDUK { - ext.args = 'trimq=10 qtrim=r' - ext.prefix = { "${meta.id}.trim" } - } + // withName: BBMAP_BBDUK { + // ext.args = 'trimq=10 qtrim=r' + // ext.prefix = { "${meta.id}.trim" } + // } } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_PE.config b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_PE.config new file mode 100644 index 000000000000..3f8fdfe1125e --- /dev/null +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_PE.config @@ -0,0 +1,6 @@ +process { + + withName: TRIMMOMATIC { + ext.args = 'ILLUMINACLIP:TruSeq3-PE.fa:2:30:10 LEADING:3 TRAILING:3 SLIDINGWINDOW:4:15 MINLEN:36' + } +} diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_SE.config b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_SE.config new file mode 100644 index 000000000000..af777fda0427 --- /dev/null +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_SE.config @@ -0,0 +1,6 @@ +process { + + withName: TRIMMOMATIC { + ext.args = 'ILLUMINACLIP:TruSeq3-SE:2:30:10 LEADING:3 TRAILING:3 SLIDINGWINDOW:4:15 MINLEN:36' + } +} From c7ef10cfb993d330eedd1b44a427e43f9ec91e59 Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Mon, 8 Dec 2025 18:17:49 +0000 Subject: [PATCH 30/83] cutadapt revisit --- .../fastq_removeadapters_merge/main.nf | 21 +-- .../fastq_removeadapters_merge/meta.yml | 6 +- .../tests/main.nf.test | 43 +++++- .../tests/main.nf.test.snap | 123 +++++++++++++++++- .../tests/nextflow.config | 6 +- 5 files changed, 176 insertions(+), 23 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index 61e51ebebe03..566e4f78e260 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -1,6 +1,6 @@ // ok for single end adapter removal include { TRIMMOMATIC } from '../../../modules/nf-core/trimmomatic/main' // both SE and PE -// include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' +include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' // both SE and PE // include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' // include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' // // allows merging of paired end reads, but will work for single end reads as well @@ -15,7 +15,7 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { take: reads // channel: [ val(meta), [ reads ] ] skip_trimmomatic // boolean - // skip_cutadapt // boolean + skip_cutadapt // boolean // skip_trimgalore // boolean // skip_bbduk // boolean // skip_fastp // boolean @@ -32,23 +32,25 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { ch_trimmomatic_trim_log = channel.empty() ch_trimmomatic_out_log = channel.empty() ch_trimmomatic_summary = channel.empty() + ch_cutadapt_log = channel.empty() ch_versions = channel.empty() if (!skip_trimmomatic) { TRIMMOMATIC( ch_reads ) - ch_reads = TRIMMOMATIC.out.trimmed_reads // .map { meta, r -> [meta, r] } // TODO remove probably + ch_reads = TRIMMOMATIC.out.trimmed_reads ch_trimmomatic_unpaired_reads = TRIMMOMATIC.out.unpaired_reads ch_trimmomatic_trim_log = TRIMMOMATIC.out.trim_log ch_trimmomatic_out_log = TRIMMOMATIC.out.out_log ch_trimmomatic_summary = TRIMMOMATIC.out.summary - ch_versions = ch_versions.mix(TRIMMOMATIC.out.versions) + ch_versions = ch_versions.mix(TRIMMOMATIC.out.versions.first()) } -// if (!skip_cutadapt) { -// CUTADAPT( ch_reads ) -// ch_reads = CUTADAPT.out.reads.map { meta, r -> [meta, r] } -// ch_versions = ch_versions.mix(CUTADAPT.out.versions) -// } + if (!skip_cutadapt) { + CUTADAPT( ch_reads ) + ch_reads = CUTADAPT.out.reads + ch_cutadapt_log = CUTADAPT.out.log + ch_versions = ch_versions.mix(CUTADAPT.out.versions.first()) + } // if (!skip_trimgalore) { // TRIMGALORE( ch_reads ) @@ -129,5 +131,6 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { trimmomatic_trim_log = ch_trimmomatic_trim_log // channel: [ val(meta), [ log ] ] trimmomatic_out_log = ch_trimmomatic_out_log // channel: [ val(meta), [ log ] ] trimmomatic_summary = ch_trimmomatic_summary // channel: [ val(meta), [ summary ] ] + cutadapt_log = ch_cutadapt_log // channel: [ val(meta), [ log ] ] versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml index 3ab05df2e8d7..19544fd21e18 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml +++ b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml @@ -7,9 +7,9 @@ keywords: - short reads - merge - trim - - trimmomatic components: - trimmomatic + - cutadapt input: - ch_reads: type: file @@ -41,6 +41,10 @@ output: type: file description: trimmomatic summary file of surviving and dropped reads pattern: "*.summary" + - cutadapt_log: + type: file + description: cuatadapt log file + pattern: "*cutadapt.log" - versions: type: file description: | diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index caec48f20652..e356a5e63800 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -3,13 +3,13 @@ nextflow_workflow { name "Test Subworkflow FASTQ_REMOVEADAPTERS_MERGE" script "../main.nf" workflow "FASTQ_REMOVEADAPTERS_MERGE" - // config './nextflow.config' + config './nextflow.config' tag "subworkflows" tag "subworkflows_nfcore" tag "subworkflows/fastq_removeadapters_merge" tag "trimmomatic" - // tag "cutadapt" + tag "cutadapt" // tag "trimgalore" // tag "bbmap" // tag "bbmap/bbduk" @@ -29,7 +29,7 @@ nextflow_workflow { ] input[1] = false // skip_trimmomatic - // input[2] = false // skip_cutadapt + input[2] = false // skip_cutadapt // input[3] = false // skip_trimgalore // input[4] = false // skip_bbduk // input[5] = false // skip_fastp @@ -46,10 +46,10 @@ nextflow_workflow { assert workflow.success assert snapshot( workflow.out.reads[0][1], - // workflow.out.trimmomatic_unpaired_reads[0][1], workflow.out.trimmomatic_trim_log[0][1], file(workflow.out.trimmomatic_out_log[0][1]).name, workflow.out.trimmomatic_summary[0][1], + workflow.out.cutadapt_log[0][1], workflow.out.versions.collect { path(it).yaml } ).match() } @@ -69,7 +69,7 @@ nextflow_workflow { ] input[1] = false // skip_trimmomatic - // input[2] = false // skip_cutadapt + input[2] = false // skip_cutadapt // input[3] = false // skip_trimgalore // input[4] = false // skip_bbduk // input[5] = false // skip_fastp @@ -90,6 +90,7 @@ nextflow_workflow { workflow.out.trimmomatic_trim_log[0][1], file(workflow.out.trimmomatic_out_log[0][1]).name, workflow.out.trimmomatic_summary[0][1], + workflow.out.cutadapt_log[0][1], workflow.out.versions.collect { path(it).yaml } ).match() } @@ -131,4 +132,36 @@ nextflow_workflow { // } // } + test("sarscov2 - fastq - single-end - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = [ + [ id:'test', single_end:true ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ] + + input[1] = false // skip_trimmomatic + input[2] = true // skip_cutadapt + // input[3] = false // skip_trimgalore + // input[4] = false // skip_bbduk + // input[5] = false // skip_fastp + // input[6] = false // skip_adapterremoval + // input[7] = false // skip_leehom + // input[8] = true // skip_ngmerge + // input[9] = false // do_merge + // input[10] = [] + """ + } + } + + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + } + } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap index 54740e44c99c..3869fa52f524 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap @@ -1,9 +1,110 @@ { + "sarscov2 - fastq - single-end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.SE.paired.trim.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test_trim.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test_out.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": true + }, + "test.summary:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" + ], + "cutadapt_log": [ + + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.SE.paired.trim.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "trimmomatic_out_log": [ + [ + { + "id": "test", + "single_end": true + }, + "test_out.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trimmomatic_summary": [ + [ + { + "id": "test", + "single_end": true + }, + "test.summary:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trimmomatic_trim_log": [ + [ + { + "id": "test", + "single_end": true + }, + "test_trim.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trimmomatic_unpaired_reads": [ + + ], + "versions": [ + "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-08T18:16:08.359216287" + }, "sarscov2 - fastq - paired-end": { "content": [ [ - "test.paired.trim_1.fastq.gz:md5,a866e64f451745f176316d0df7d52b30", - "test.paired.trim_2.fastq.gz:md5,725d4ab909b39291ab56b090cab32075" + "test_1.trim.fastq.gz:md5,b4b94f4e66a13b93e7e6e8a6b1264dfd", + "test_2.trim.fastq.gz:md5,3038963f2f64c3d73e1fa21dfb8c32ef" ], [ "test.unpaired.trim_1.fastq.gz:md5,f22935d14248bd936af8d5e3c27e72b2", @@ -12,11 +113,17 @@ "test_trim.log:md5,9629761761a34576b3484bf4174f681f", "test_out.log", "test.summary:md5,9698e5e5c060bbe64588998fe35f8d71", + "test.cutadapt.log:md5,8da32e029f7c4b891930cc656abea887", [ { "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { "trimmomatic": 0.39 } + }, + { + "FASTQ_REMOVEADAPTERS_MERGE:CUTADAPT": { + "cutadapt": 5.0 + } } ] ], @@ -24,19 +131,25 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T17:49:41.579082238" + "timestamp": "2025-12-08T18:07:10.760662398" }, "sarscov2 - fastq - single-end": { "content": [ - "test.SE.paired.trim.fastq.gz:md5,e68abbd3b88f7ec12940a4f5c2b8bfb9", + "test.trim.fastq.gz:md5,cc70531f77439cf2b63fb32552716b48", "test_trim.log:md5,e4c3f619e9b0e26847f8f3e3d9af319b", "test_out.log", "test.summary:md5,24c973237557a1439c775ca19a5deaa5", + "test.cutadapt.log:md5,7cbd396c162d74ec27ae2f88834b5685", [ { "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { "trimmomatic": 0.39 } + }, + { + "FASTQ_REMOVEADAPTERS_MERGE:CUTADAPT": { + "cutadapt": 5.0 + } } ] ], @@ -44,6 +157,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T17:48:51.793945465" + "timestamp": "2025-12-08T18:07:03.721999339" } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config index 0e9f544cd2a1..b433fde30af3 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config @@ -1,7 +1,7 @@ process { - // withName: CUTADAPT { - // ext.args = '-q 25' - // } + withName: CUTADAPT { + ext.args = '-q 25' + } // withName: BBMAP_BBDUK { // ext.args = 'trimq=10 qtrim=r' From ca4db6288cbaf09df3f99a63b1930498756e3233 Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Mon, 8 Dec 2025 18:48:13 +0000 Subject: [PATCH 31/83] trimgalore revisit --- .../fastq_removeadapters_merge/main.nf | 24 ++++-- .../fastq_removeadapters_merge/meta.yml | 31 ++++++++ .../tests/main.nf.test | 11 ++- .../tests/main.nf.test.snap | 73 ++++++++++++++++--- 4 files changed, 118 insertions(+), 21 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index 566e4f78e260..2248a0b887f0 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -1,7 +1,7 @@ // ok for single end adapter removal include { TRIMMOMATIC } from '../../../modules/nf-core/trimmomatic/main' // both SE and PE include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' // both SE and PE -// include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' +include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' // both SE and PE // include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' // // allows merging of paired end reads, but will work for single end reads as well // include { FASTP } from '../../../modules/nf-core/fastp/main' @@ -16,7 +16,7 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { reads // channel: [ val(meta), [ reads ] ] skip_trimmomatic // boolean skip_cutadapt // boolean - // skip_trimgalore // boolean + skip_trimgalore // boolean // skip_bbduk // boolean // skip_fastp // boolean // skip_adapterremoval // boolean @@ -52,11 +52,15 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { ch_versions = ch_versions.mix(CUTADAPT.out.versions.first()) } -// if (!skip_trimgalore) { -// TRIMGALORE( ch_reads ) -// ch_reads = TRIMGALORE.out.reads.map { meta, r -> [meta, r] } -// ch_versions = ch_versions.mix(TRIMGALORE.out.versions) -// } + if (!skip_trimgalore) { + TRIMGALORE( ch_reads ) + ch_reads = TRIMGALORE.out.reads + ch_trimgalore_log = TRIMGALORE.out.log + ch_trimgalore_unpaired = TRIMGALORE.out.unpaired + ch_trimgalore_html = TRIMGALORE.out.html + ch_trimgalore_zip = TRIMGALORE.out.zip + ch_versions = ch_versions.mix(TRIMGALORE.out.versions.first()) + } // if (!skip_bbduk) { // ch_reads.view { "DEBUG: BEFORE BBMAP_BBDUK → $it" } @@ -132,5 +136,9 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { trimmomatic_out_log = ch_trimmomatic_out_log // channel: [ val(meta), [ log ] ] trimmomatic_summary = ch_trimmomatic_summary // channel: [ val(meta), [ summary ] ] cutadapt_log = ch_cutadapt_log // channel: [ val(meta), [ log ] ] - versions = ch_versions // channel: [ versions.yml ] + trimgalore_log = ch_trimgalore_log // channel: [ val(meta), [ txt ] ] + trimgalore_unpaired = ch_trimgalore_unpaired // channel: [ val(meta), [ fq.gz ] ] + trimgalore_html = ch_trimgalore_html // channel: [ val(meta), [ html ] ] + trimgalore_zip = ch_trimgalore_zip // channel: [ val(meta), [ zip ] ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml index 19544fd21e18..47bc2d915288 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml +++ b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml @@ -10,6 +10,7 @@ keywords: components: - trimmomatic - cutadapt + - trimgalore input: - ch_reads: type: file @@ -20,6 +21,16 @@ input: type: boolean description: | If true, skips the trimmomatic process. + - skip_cutadapt: + type: boolean + description: | + If true, skips the cutadapt process. + - skip_trimgalore: + type: boolean + description: | + If true, skips the trimgalore process. + We suggest running either cutadapt or trimgalore, + because trimgalore also runs cutadapt in the background. output: - reads: type: file @@ -45,6 +56,26 @@ output: type: file description: cuatadapt log file pattern: "*cutadapt.log" + - trimgalore_log: + type: file + description: | + trimgalore log file + pattern: "*_{report.txt}" + - trimgalore_unpaired: + type: file + description: | + Unpaired trimgalore reads. Activate with the --retain_unpaired flag. + pattern: "*unpaired*.fq.gz" + - trimgalore_html: + type: file + description: | + fastqc HTML output if run with the --fastqc flag. + pattern: "*_{fastqc.html}" + - trimgalore_zip: + type: file + description: | + fastqc zip output if run with the --fastqc flag. + pattern: "*_{fastqc.zip}" - versions: type: file description: | diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index e356a5e63800..fcfb3f8e3c65 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -10,7 +10,7 @@ nextflow_workflow { tag "subworkflows/fastq_removeadapters_merge" tag "trimmomatic" tag "cutadapt" - // tag "trimgalore" + tag "trimgalore" // tag "bbmap" // tag "bbmap/bbduk" // tag "fastp" @@ -30,7 +30,7 @@ nextflow_workflow { input[1] = false // skip_trimmomatic input[2] = false // skip_cutadapt - // input[3] = false // skip_trimgalore + input[3] = false // skip_trimgalore // input[4] = false // skip_bbduk // input[5] = false // skip_fastp // input[6] = false // skip_adapterremoval @@ -50,6 +50,7 @@ nextflow_workflow { file(workflow.out.trimmomatic_out_log[0][1]).name, workflow.out.trimmomatic_summary[0][1], workflow.out.cutadapt_log[0][1], + path(workflow.out.trimgalore_log[0][1]).readLines().size(), workflow.out.versions.collect { path(it).yaml } ).match() } @@ -70,7 +71,7 @@ nextflow_workflow { input[1] = false // skip_trimmomatic input[2] = false // skip_cutadapt - // input[3] = false // skip_trimgalore + input[3] = false // skip_trimgalore // input[4] = false // skip_bbduk // input[5] = false // skip_fastp // input[6] = false // skip_adapterremoval @@ -91,6 +92,8 @@ nextflow_workflow { file(workflow.out.trimmomatic_out_log[0][1]).name, workflow.out.trimmomatic_summary[0][1], workflow.out.cutadapt_log[0][1], + path(workflow.out.trimgalore_log[0][1][0]).readLines().size(), + path(workflow.out.trimgalore_log[0][1][1]).readLines().size(), workflow.out.versions.collect { path(it).yaml } ).match() } @@ -146,7 +149,7 @@ nextflow_workflow { input[1] = false // skip_trimmomatic input[2] = true // skip_cutadapt - // input[3] = false // skip_trimgalore + input[3] = false // skip_trimgalore // input[4] = false // skip_bbduk // input[5] = false // skip_fastp // input[6] = false // skip_adapterremoval diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap index 3869fa52f524..b5174934b80a 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap @@ -8,11 +8,15 @@ "id": "test", "single_end": true }, - "test.SE.paired.trim.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "1": [ + ], + "10": [ + "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", + "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" ], "2": [ [ @@ -45,7 +49,22 @@ ], "6": [ - "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" + [ + { + "id": "test", + "single_end": true + }, + "test.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + + ], + "8": [ + + ], + "9": [ + ], "cutadapt_log": [ @@ -56,8 +75,26 @@ "id": "test", "single_end": true }, - "test.SE.paired.trim.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "trimgalore_html": [ + + ], + "trimgalore_log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] + ], + "trimgalore_unpaired": [ + + ], + "trimgalore_zip": [ + ], "trimmomatic_out_log": [ [ @@ -90,6 +127,7 @@ ], "versions": [ + "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" ] } @@ -98,13 +136,13 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T18:16:08.359216287" + "timestamp": "2025-12-08T18:27:04.215969504" }, "sarscov2 - fastq - paired-end": { "content": [ [ - "test_1.trim.fastq.gz:md5,b4b94f4e66a13b93e7e6e8a6b1264dfd", - "test_2.trim.fastq.gz:md5,3038963f2f64c3d73e1fa21dfb8c32ef" + "test_1_val_1.fq.gz:md5,d6bc1cc12ca00a83307a4233ab006ab7", + "test_2_val_2.fq.gz:md5,81d8c05733feff95655f989143349a0c" ], [ "test.unpaired.trim_1.fastq.gz:md5,f22935d14248bd936af8d5e3c27e72b2", @@ -114,7 +152,16 @@ "test_out.log", "test.summary:md5,9698e5e5c060bbe64588998fe35f8d71", "test.cutadapt.log:md5,8da32e029f7c4b891930cc656abea887", + 60, + 63, [ + { + "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { + "trimgalore": "0.6.10", + "cutadapt": 4.9, + "pigz": 2.8 + } + }, { "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { "trimmomatic": 0.39 @@ -131,16 +178,24 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T18:07:10.760662398" + "timestamp": "2025-12-08T18:46:25.911604926" }, "sarscov2 - fastq - single-end": { "content": [ - "test.trim.fastq.gz:md5,cc70531f77439cf2b63fb32552716b48", + "test_trimmed.fq.gz:md5,827097b00cdc45f16497c19bfa719bf8", "test_trim.log:md5,e4c3f619e9b0e26847f8f3e3d9af319b", "test_out.log", "test.summary:md5,24c973237557a1439c775ca19a5deaa5", "test.cutadapt.log:md5,7cbd396c162d74ec27ae2f88834b5685", + 61, [ + { + "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { + "trimgalore": "0.6.10", + "cutadapt": 4.9, + "pigz": 2.8 + } + }, { "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { "trimmomatic": 0.39 @@ -157,6 +212,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T18:07:03.721999339" + "timestamp": "2025-12-08T18:45:23.409047165" } } \ No newline at end of file From 54863da89aa9349643dba19e2bc700708d86a6c8 Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Mon, 8 Dec 2025 19:11:26 +0000 Subject: [PATCH 32/83] bbduk revisit --- .../fastq_removeadapters_merge/main.nf | 26 ++++---- .../fastq_removeadapters_merge/meta.yml | 19 +++++- .../tests/main.nf.test | 60 ++++++++++--------- .../tests/main.nf.test.snap | 48 ++++++++++++--- .../tests/nextflow.config | 7 +-- 5 files changed, 106 insertions(+), 54 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index 2248a0b887f0..d01e0e8adf39 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -2,7 +2,7 @@ include { TRIMMOMATIC } from '../../../modules/nf-core/trimmomatic/main' // both SE and PE include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' // both SE and PE include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' // both SE and PE -// include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' +include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' // both SE and PE // // allows merging of paired end reads, but will work for single end reads as well // include { FASTP } from '../../../modules/nf-core/fastp/main' // include { ADAPTERREMOVAL} from '../../../modules/nf-core/adapterremoval/main' @@ -17,13 +17,14 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { skip_trimmomatic // boolean skip_cutadapt // boolean skip_trimgalore // boolean - // skip_bbduk // boolean + skip_bbduk // boolean + contaminants // channel: [ reads ] // skip_fastp // boolean // skip_adapterremoval // boolean // skip_leehom // boolean // skip_ngmerge // boolean // do_merge - // adapters_contaminants + // adapters_ main: @@ -33,6 +34,11 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { ch_trimmomatic_out_log = channel.empty() ch_trimmomatic_summary = channel.empty() ch_cutadapt_log = channel.empty() + ch_trimgalore_log = channel.empty() + ch_trimgalore_unpaired = channel.empty() + ch_trimgalore_html = channel.empty() + ch_trimgalore_zip = channel.empty() + ch_bbduk_log = channel.empty() ch_versions = channel.empty() if (!skip_trimmomatic) { @@ -62,13 +68,12 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { ch_versions = ch_versions.mix(TRIMGALORE.out.versions.first()) } -// if (!skip_bbduk) { -// ch_reads.view { "DEBUG: BEFORE BBMAP_BBDUK → $it" } -// BBMAP_BBDUK( ch_reads, adapters_contaminants ) -// ch_reads = BBMAP_BBDUK.out.reads.map { meta, r -> [meta, r] } -// ch_versions = ch_versions.mix(BBMAP_BBDUK.out.versions) -// ch_reads.view { "DEBUG: AFTER BBMAP_BBDUK → $it" } -// } + if (!skip_bbduk) { + BBMAP_BBDUK( ch_reads, contaminants ) + ch_reads = BBMAP_BBDUK.out.reads + ch_bbduk_log = BBMAP_BBDUK.out.log + ch_versions = ch_versions.mix(BBMAP_BBDUK.out.versions.first()) + } // if (!skip_fastp && !do_merge) { // ch_reads.view { "DEBUG: BEFORE FASTP → $it" } @@ -140,5 +145,6 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { trimgalore_unpaired = ch_trimgalore_unpaired // channel: [ val(meta), [ fq.gz ] ] trimgalore_html = ch_trimgalore_html // channel: [ val(meta), [ html ] ] trimgalore_zip = ch_trimgalore_zip // channel: [ val(meta), [ zip ] ] + bbduk_log = ch_bbduk_log // channel: [ val(meta), [ log ] ] versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml index 47bc2d915288..9f0c61872465 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml +++ b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml @@ -11,6 +11,7 @@ components: - trimmomatic - cutadapt - trimgalore + - bbmap/bbduk input: - ch_reads: type: file @@ -31,6 +32,14 @@ input: If true, skips the trimgalore process. We suggest running either cutadapt or trimgalore, because trimgalore also runs cutadapt in the background. + - skip_bbduk: + type: boolean + description: | + If true, skips the bbmap/bbduk process. + - contaminants: + type: file + description: | + Reference files used by bbmap/bbduk, containing adapter and/or contaminant sequences for sequence kmer matching output: - reads: type: file @@ -60,7 +69,7 @@ output: type: file description: | trimgalore log file - pattern: "*_{report.txt}" + pattern: "*_report.txt" - trimgalore_unpaired: type: file description: | @@ -70,12 +79,16 @@ output: type: file description: | fastqc HTML output if run with the --fastqc flag. - pattern: "*_{fastqc.html}" + pattern: "*_fastqc.html" - trimgalore_zip: type: file description: | fastqc zip output if run with the --fastqc flag. - pattern: "*_{fastqc.zip}" + pattern: "*_fastqc.zip" + - bbduk_log: + type: file + description: Bbduk log file + pattern: "*bbduk.log" - versions: type: file description: | diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index fcfb3f8e3c65..ae6b3586fffe 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -11,8 +11,8 @@ nextflow_workflow { tag "trimmomatic" tag "cutadapt" tag "trimgalore" - // tag "bbmap" - // tag "bbmap/bbduk" + tag "bbmap" + tag "bbmap/bbduk" // tag "fastp" // tag "adapterremoval" // tag "leehom" @@ -31,13 +31,13 @@ nextflow_workflow { input[1] = false // skip_trimmomatic input[2] = false // skip_cutadapt input[3] = false // skip_trimgalore - // input[4] = false // skip_bbduk - // input[5] = false // skip_fastp - // input[6] = false // skip_adapterremoval - // input[7] = false // skip_leehom - // input[8] = true // skip_ngmerge - // input[9] = false // do_merge - // input[10] = [] + input[4] = false // skip_bbduk + input[5] = [] // contaminants + // input[6] = false // skip_fastp + // input[7] = false // skip_adapterremoval + // input[8] = false // skip_leehom + // input[9] = true // skip_ngmerge + // input[10] = false // do_merge """ } } @@ -51,6 +51,7 @@ nextflow_workflow { workflow.out.trimmomatic_summary[0][1], workflow.out.cutadapt_log[0][1], path(workflow.out.trimgalore_log[0][1]).readLines().size(), + path(workflow.out.bbduk_log[0][1]).readLines().size(), workflow.out.versions.collect { path(it).yaml } ).match() } @@ -72,13 +73,13 @@ nextflow_workflow { input[1] = false // skip_trimmomatic input[2] = false // skip_cutadapt input[3] = false // skip_trimgalore - // input[4] = false // skip_bbduk - // input[5] = false // skip_fastp - // input[6] = false // skip_adapterremoval - // input[7] = false // skip_leehom - // input[8] = true // skip_ngmerge - // input[9] = false // do_merge - // input[10] = [] + input[4] = false // skip_bbduk + input[5] = [] // contaminants + // input[6] = false // skip_fastp + // input[7] = false // skip_adapterremoval + // input[8] = false // skip_leehom + // input[9] = true // skip_ngmerge + // input[10] = false // do_merge """ } } @@ -94,6 +95,7 @@ nextflow_workflow { workflow.out.cutadapt_log[0][1], path(workflow.out.trimgalore_log[0][1][0]).readLines().size(), path(workflow.out.trimgalore_log[0][1][1]).readLines().size(), + path(workflow.out.bbduk_log[0][1]).readLines().size(), workflow.out.versions.collect { path(it).yaml } ).match() } @@ -117,12 +119,12 @@ nextflow_workflow { // input[2] = false // skip_cutadapt // input[3] = false // skip_trimgalore // input[4] = false // skip_bbduk - // input[5] = false // skip_fastp - // input[6] = false // skip_adapterremoval - // input[7] = false // skip_leehom - // input[8] = true // skip_ngmerge - // input[9] = false // do_merge - // input[10] = [] + // input[5] = [] // contaminants + // input[6] = false // skip_fastp + // input[7] = false // skip_adapterremoval + // input[8] = false // skip_leehom + // input[9] = true // skip_ngmerge + // input[10] = false // do_merge // """ // } // } @@ -150,13 +152,13 @@ nextflow_workflow { input[1] = false // skip_trimmomatic input[2] = true // skip_cutadapt input[3] = false // skip_trimgalore - // input[4] = false // skip_bbduk - // input[5] = false // skip_fastp - // input[6] = false // skip_adapterremoval - // input[7] = false // skip_leehom - // input[8] = true // skip_ngmerge - // input[9] = false // do_merge - // input[10] = [] + input[4] = false // skip_bbduk + input[5] = [] // contaminants + // input[6] = false // skip_fastp + // input[7] = false // skip_adapterremoval + // input[8] = false // skip_leehom + // input[9] = true // skip_ngmerge + // input[10] = false // do_merge """ } } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap index b5174934b80a..62810d2fd8d2 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap @@ -8,14 +8,24 @@ "id": "test", "single_end": true }, - "test_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "1": [ ], "10": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "11": [ "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", + "versions.yml:md5,bcfe22d952cc3ae0ac5ff685e16fa4a5", "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" ], "2": [ @@ -65,6 +75,15 @@ ], "9": [ + ], + "bbduk_log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ], "cutadapt_log": [ @@ -75,7 +94,7 @@ "id": "test", "single_end": true }, - "test_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "trimgalore_html": [ @@ -128,6 +147,7 @@ ], "versions": [ "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", + "versions.yml:md5,bcfe22d952cc3ae0ac5ff685e16fa4a5", "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" ] } @@ -136,13 +156,13 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T18:27:04.215969504" + "timestamp": "2025-12-08T19:04:49.308865964" }, "sarscov2 - fastq - paired-end": { "content": [ [ - "test_1_val_1.fq.gz:md5,d6bc1cc12ca00a83307a4233ab006ab7", - "test_2_val_2.fq.gz:md5,81d8c05733feff95655f989143349a0c" + "test_1.fastq.gz:md5,d6bc1cc12ca00a83307a4233ab006ab7", + "test_2.fastq.gz:md5,81d8c05733feff95655f989143349a0c" ], [ "test.unpaired.trim_1.fastq.gz:md5,f22935d14248bd936af8d5e3c27e72b2", @@ -154,6 +174,7 @@ "test.cutadapt.log:md5,8da32e029f7c4b891930cc656abea887", 60, 63, + 21, [ { "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { @@ -162,6 +183,11 @@ "pigz": 2.8 } }, + { + "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { + "bbmap": 39.18 + } + }, { "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { "trimmomatic": 0.39 @@ -178,16 +204,17 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T18:46:25.911604926" + "timestamp": "2025-12-08T19:07:31.612741363" }, "sarscov2 - fastq - single-end": { "content": [ - "test_trimmed.fq.gz:md5,827097b00cdc45f16497c19bfa719bf8", + "test.fastq.gz:md5,827097b00cdc45f16497c19bfa719bf8", "test_trim.log:md5,e4c3f619e9b0e26847f8f3e3d9af319b", "test_out.log", "test.summary:md5,24c973237557a1439c775ca19a5deaa5", "test.cutadapt.log:md5,7cbd396c162d74ec27ae2f88834b5685", 61, + 21, [ { "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { @@ -196,6 +223,11 @@ "pigz": 2.8 } }, + { + "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { + "bbmap": 39.18 + } + }, { "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { "trimmomatic": 0.39 @@ -212,6 +244,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T18:45:23.409047165" + "timestamp": "2025-12-08T19:07:17.093246038" } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config index b433fde30af3..ebd460bf9ecf 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config @@ -3,9 +3,8 @@ process { ext.args = '-q 25' } - // withName: BBMAP_BBDUK { - // ext.args = 'trimq=10 qtrim=r' - // ext.prefix = { "${meta.id}.trim" } - // } + withName: BBMAP_BBDUK { + ext.args = 'trimq=10 qtrim=r' + } } From 697d9435200e383160cefd444a248a2e64a79ba0 Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Mon, 8 Dec 2025 20:00:06 +0000 Subject: [PATCH 33/83] fastp revisit --- .../fastq_removeadapters_merge/main.nf | 62 +++++---- .../fastq_removeadapters_merge/meta.yml | 42 ++++++- .../tests/main.nf.test | 56 ++++++--- .../tests/main.nf.test.snap | 118 ++++++++++++++++-- 4 files changed, 226 insertions(+), 52 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index d01e0e8adf39..ea587e00204c 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -4,7 +4,7 @@ include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' // bo include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' // both SE and PE include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' // both SE and PE // // allows merging of paired end reads, but will work for single end reads as well -// include { FASTP } from '../../../modules/nf-core/fastp/main' +include { FASTP } from '../../../modules/nf-core/fastp/main' // both SE and PE + merge // include { ADAPTERREMOVAL} from '../../../modules/nf-core/adapterremoval/main' // include { LEEHOM } from '../../../modules/nf-core/leehom/main' // // requires paired end because of merging @@ -13,18 +13,19 @@ include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' // bo workflow FASTQ_REMOVEADAPTERS_MERGE { take: - reads // channel: [ val(meta), [ reads ] ] - skip_trimmomatic // boolean - skip_cutadapt // boolean - skip_trimgalore // boolean - skip_bbduk // boolean - contaminants // channel: [ reads ] - // skip_fastp // boolean - // skip_adapterremoval // boolean - // skip_leehom // boolean - // skip_ngmerge // boolean - // do_merge - // adapters_ + reads // channel: [ val(meta), [ reads ] ] + skip_trimmomatic // boolean + skip_cutadapt // boolean + skip_trimgalore // boolean + skip_bbduk // boolean + contaminants // channel: [ reads ] // fasta, adapters to remove + skip_fastp // boolean + fastp_discard_trimmed_pass // boolean + fastp_save_trimmed_fail // boolean + save_merged // boolean + // skip_adapterremoval // boolean + // skip_leehom // boolean + // skip_ngmerge // boolean main: @@ -39,6 +40,11 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { ch_trimgalore_html = channel.empty() ch_trimgalore_zip = channel.empty() ch_bbduk_log = channel.empty() + ch_fastp_json = channel.empty() + ch_fastp_html = channel.empty() + ch_fastp_log = channel.empty() + ch_fastp_reads_fail = channel.empty() + ch_fastp_reads_merged = channel.empty() ch_versions = channel.empty() if (!skip_trimmomatic) { @@ -75,16 +81,21 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { ch_versions = ch_versions.mix(BBMAP_BBDUK.out.versions.first()) } -// if (!skip_fastp && !do_merge) { -// ch_reads.view { "DEBUG: BEFORE FASTP → $it" } -// FASTP( ch_reads.map { meta, r -> tuple(meta, r, adapters_contaminants)}, -// false, -// true, -// do_merge) -// ch_reads = FASTP.out.reads.map { meta, r -> [meta, r] } -// ch_versions = ch_versions.mix(FASTP.out.versions) -// ch_reads.view { "DEBUG: AFTER FASTP → $it" } -// } + if (!skip_fastp) { + FASTP( + ch_reads.map { meta, files -> [ meta, files, contaminants ] }, + fastp_discard_trimmed_pass, + fastp_save_trimmed_fail, + save_merged + ) + ch_reads = FASTP.out.reads + ch_fastp_json = FASTP.out.json + ch_fastp_html = FASTP.out.html + ch_fastp_log = FASTP.out.log + ch_fastp_reads_fail = FASTP.out.reads_fail + ch_fastp_reads_merged = FASTP.out.reads_merged + ch_versions = ch_versions.mix(FASTP.out.versions.first()) + } // if (!skip_adapterremoval && !do_merge) { // ADAPTERREMOVAL( ch_reads, adapters_contaminants ) @@ -146,5 +157,10 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { trimgalore_html = ch_trimgalore_html // channel: [ val(meta), [ html ] ] trimgalore_zip = ch_trimgalore_zip // channel: [ val(meta), [ zip ] ] bbduk_log = ch_bbduk_log // channel: [ val(meta), [ log ] ] + fastp_json = ch_fastp_json // channel: [ val(meta), [ json ] ] + fastp_html = ch_fastp_html // channel: [ val(meta), [ html ] ] + fastp_log = ch_fastp_log // channel: [ val(meta), [ log ] ] + fastp_reads_fail = ch_fastp_reads_fail // channel: [ val(meta), [ fastq.gz ] ] + fastp_reads_merged = ch_fastp_reads_merged // channel: [ val(meta), [ fastq.gz ] ] versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml index 9f0c61872465..2347a1cc99e9 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml +++ b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml @@ -12,6 +12,7 @@ components: - cutadapt - trimgalore - bbmap/bbduk + - fastp input: - ch_reads: type: file @@ -39,7 +40,26 @@ input: - contaminants: type: file description: | - Reference files used by bbmap/bbduk, containing adapter and/or contaminant sequences for sequence kmer matching + Reference files used by bbmap/bbduk and/or fastp, containing adapter and/or contaminant sequences for removal + - skip_fastp: + type: boolean + description: | + If true, skips the fastp process. + - fastp_discard_trimmed_pass: + type: boolean + description: | + Specify true to not write any reads that pass trimming thresholds from the fastp process. + This can be used to use fastp for the output report only. + - fastp_save_trimmed_fail: + type: boolean + description: | + Specify true to save files that failed to pass fastp trimming thresholds + ending in `*.fail.fastq.gz` + - save_merged: + type: boolean + description: | + Specify true to save all merged reads to a file ending in `*.merged.fastq.gz` + Used by fastp output: - reads: type: file @@ -89,6 +109,26 @@ output: type: file description: Bbduk log file pattern: "*bbduk.log" + - fastp_json: + type: file + description: fastp results in JSON format + pattern: "*.json" + - fastp_html: + type: file + description: fastp results in HTML format + pattern: "*.html" + - fastp_log: + type: file + description: fastp fastq log file + pattern: "*.log" + - fastp_reads_fail: + type: file + description: fastp reads that failed the preprocessing + pattern: "*fail.fastq.gz" + - fastp_reads_merged: + type: file + description: fastp reads that were successfully merged + pattern: "*.merged.fastq.gz" - versions: type: file description: | diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index ae6b3586fffe..f496f291e474 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -13,7 +13,7 @@ nextflow_workflow { tag "trimgalore" tag "bbmap" tag "bbmap/bbduk" - // tag "fastp" + tag "fastp" // tag "adapterremoval" // tag "leehom" // tag "ngmerge" @@ -33,11 +33,13 @@ nextflow_workflow { input[3] = false // skip_trimgalore input[4] = false // skip_bbduk input[5] = [] // contaminants - // input[6] = false // skip_fastp - // input[7] = false // skip_adapterremoval - // input[8] = false // skip_leehom - // input[9] = true // skip_ngmerge - // input[10] = false // do_merge + input[6] = false // skip_fastp + input[7] = false // fastp_discard_trimmed_pass + input[8] = true // fastp_save_trimmed_fail + input[9] = true // save_merged + // input[10] = false // skip_adapterremoval + // input[11] = false // skip_leehom + // input[12] = true // skip_ngmerge """ } } @@ -52,6 +54,10 @@ nextflow_workflow { workflow.out.cutadapt_log[0][1], path(workflow.out.trimgalore_log[0][1]).readLines().size(), path(workflow.out.bbduk_log[0][1]).readLines().size(), + workflow.out.fastp_json[0][1], + file(workflow.out.fastp_html[0][1]).name, + path(workflow.out.fastp_log[0][1]).readLines().size(), + workflow.out.fastp_reads_fail[0][1], workflow.out.versions.collect { path(it).yaml } ).match() } @@ -75,11 +81,13 @@ nextflow_workflow { input[3] = false // skip_trimgalore input[4] = false // skip_bbduk input[5] = [] // contaminants - // input[6] = false // skip_fastp - // input[7] = false // skip_adapterremoval - // input[8] = false // skip_leehom - // input[9] = true // skip_ngmerge - // input[10] = false // do_merge + input[6] = false // skip_fastp + input[7] = false // fastp_discard_trimmed_pass + input[8] = true // fastp_save_trimmed_fail + input[9] = true // save_merged + // input[10] = false // skip_adapterremoval + // input[11] = false // skip_leehom + // input[12] = true // skip_ngmerge """ } } @@ -96,6 +104,10 @@ nextflow_workflow { path(workflow.out.trimgalore_log[0][1][0]).readLines().size(), path(workflow.out.trimgalore_log[0][1][1]).readLines().size(), path(workflow.out.bbduk_log[0][1]).readLines().size(), + workflow.out.fastp_json[0][1], + file(workflow.out.fastp_html[0][1]).name, + path(workflow.out.fastp_log[0][1]).readLines().size(), + workflow.out.fastp_reads_fail[0][1].collect { file(it).name }.sort(), workflow.out.versions.collect { path(it).yaml } ).match() } @@ -121,10 +133,12 @@ nextflow_workflow { // input[4] = false // skip_bbduk // input[5] = [] // contaminants // input[6] = false // skip_fastp - // input[7] = false // skip_adapterremoval - // input[8] = false // skip_leehom - // input[9] = true // skip_ngmerge - // input[10] = false // do_merge + // input[7] = false // fastp_discard_trimmed_pass + // input[8] = true // fastp_save_trimmed_fail + // input[9] = true // save_merged + // input[10] = false // skip_adapterremoval + // input[11] = false // skip_leehom + // input[12] = true // skip_ngmerge // """ // } // } @@ -154,11 +168,13 @@ nextflow_workflow { input[3] = false // skip_trimgalore input[4] = false // skip_bbduk input[5] = [] // contaminants - // input[6] = false // skip_fastp - // input[7] = false // skip_adapterremoval - // input[8] = false // skip_leehom - // input[9] = true // skip_ngmerge - // input[10] = false // do_merge + input[6] = false // skip_fastp + input[7] = false // fastp_discard_trimmed_pass + input[8] = true // fastp_save_trimmed_fail + input[9] = true // save_merged + // input[10] = false // skip_adapterremoval + // input[11] = false // skip_leehom + // input[12] = true // skip_ngmerge """ } } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap index 62810d2fd8d2..be1380c7ff44 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap @@ -8,7 +8,7 @@ "id": "test", "single_end": true }, - "test.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "1": [ @@ -24,7 +24,47 @@ ] ], "11": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "14": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "15": [ + + ], + "16": [ "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", + "versions.yml:md5,2d5c9b99267e97292e2a581635bd72f7", "versions.yml:md5,bcfe22d952cc3ae0ac5ff685e16fa4a5", "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" ], @@ -87,6 +127,45 @@ ], "cutadapt_log": [ + ], + "fastp_html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastp_json": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastp_log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastp_reads_fail": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "fastp_reads_merged": [ + ], "reads": [ [ @@ -94,7 +173,7 @@ "id": "test", "single_end": true }, - "test.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "trimgalore_html": [ @@ -147,6 +226,7 @@ ], "versions": [ "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", + "versions.yml:md5,2d5c9b99267e97292e2a581635bd72f7", "versions.yml:md5,bcfe22d952cc3ae0ac5ff685e16fa4a5", "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" ] @@ -156,13 +236,13 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T19:04:49.308865964" + "timestamp": "2025-12-08T19:38:21.971691897" }, "sarscov2 - fastq - paired-end": { "content": [ [ - "test_1.fastq.gz:md5,d6bc1cc12ca00a83307a4233ab006ab7", - "test_2.fastq.gz:md5,81d8c05733feff95655f989143349a0c" + "test_1.fastp.fastq.gz:md5,ced67d85f7936c54e13822d3dba061c8", + "test_2.fastp.fastq.gz:md5,4d8b08322b9cbaf6258db35726f2c658" ], [ "test.unpaired.trim_1.fastq.gz:md5,f22935d14248bd936af8d5e3c27e72b2", @@ -175,6 +255,14 @@ 60, 63, 21, + "test.fastp.json:md5,5cfafac26b0bcec71a2022276904d975", + "test.fastp.html", + 51, + [ + "test.paired.fail.fastq.gz", + "test_1.fail.fastq.gz", + "test_2.fail.fastq.gz" + ], [ { "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { @@ -183,6 +271,11 @@ "pigz": 2.8 } }, + { + "FASTQ_REMOVEADAPTERS_MERGE:FASTP": { + "fastp": "1.0.1" + } + }, { "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { "bbmap": 39.18 @@ -204,17 +297,21 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T19:07:31.612741363" + "timestamp": "2025-12-08T19:58:49.88448508" }, "sarscov2 - fastq - single-end": { "content": [ - "test.fastq.gz:md5,827097b00cdc45f16497c19bfa719bf8", + "test.fastp.fastq.gz:md5,84aa1ce965cafc4a59aabeb986f1e325", "test_trim.log:md5,e4c3f619e9b0e26847f8f3e3d9af319b", "test_out.log", "test.summary:md5,24c973237557a1439c775ca19a5deaa5", "test.cutadapt.log:md5,7cbd396c162d74ec27ae2f88834b5685", 61, 21, + "test.fastp.json:md5,f1e9b92d4c11419310aee353bf048ec0", + "test.fastp.html", + 32, + "test.fail.fastq.gz:md5,3e4aaadb66a5b8fc9b881bf39c227abd", [ { "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { @@ -223,6 +320,11 @@ "pigz": 2.8 } }, + { + "FASTQ_REMOVEADAPTERS_MERGE:FASTP": { + "fastp": "1.0.1" + } + }, { "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { "bbmap": 39.18 @@ -244,6 +346,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T19:07:17.093246038" + "timestamp": "2025-12-08T19:48:31.272945778" } } \ No newline at end of file From 77cdc8c0d097cabc81977d4149c823f1a202a195 Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Tue, 9 Dec 2025 11:29:55 +0000 Subject: [PATCH 34/83] adapterremoval revisit --- .../fastq_removeadapters_merge/main.nf | 136 ++++++++------- .../fastq_removeadapters_merge/meta.yml | 48 +++--- .../tests/main.nf.test | 103 +++++++----- .../tests/main.nf.test.snap | 157 +++++++++++------- .../tests/nextflow.config | 5 +- .../tests/nextflow_PE.config | 7 +- .../tests/nextflow_SE.config | 7 +- 7 files changed, 267 insertions(+), 196 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index ea587e00204c..9d6560aef052 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -1,11 +1,12 @@ // ok for single end adapter removal -include { TRIMMOMATIC } from '../../../modules/nf-core/trimmomatic/main' // both SE and PE -include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' // both SE and PE -include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' // both SE and PE -include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' // both SE and PE +include { TRIMMOMATIC } from '../../../modules/nf-core/trimmomatic/main' // both SE and PE +include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' // both SE and PE +include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' // both SE and PE +include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' // both SE and PE // // allows merging of paired end reads, but will work for single end reads as well -include { FASTP } from '../../../modules/nf-core/fastp/main' // both SE and PE + merge -// include { ADAPTERREMOVAL} from '../../../modules/nf-core/adapterremoval/main' +include { FASTP } from '../../../modules/nf-core/fastp/main' // both SE and PE + merge +include { ADAPTERREMOVAL as ADAPTERREMOVAL_SE } from '../../../modules/nf-core/adapterremoval/main' +include { ADAPTERREMOVAL as ADAPTERREMOVAL_PE } from '../../../modules/nf-core/adapterremoval/main' // include { LEEHOM } from '../../../modules/nf-core/leehom/main' // // requires paired end because of merging // include { NGMERGE } from '../../../modules/nf-core/ngmerge/main' @@ -23,45 +24,45 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { fastp_discard_trimmed_pass // boolean fastp_save_trimmed_fail // boolean save_merged // boolean - // skip_adapterremoval // boolean + skip_adapterremoval // boolean + text_adapters // channel: [ txt ] // adapters to remove, in adapterremoval text format // skip_leehom // boolean // skip_ngmerge // boolean main: - ch_reads = reads - ch_trimmomatic_unpaired_reads = channel.empty() - ch_trimmomatic_trim_log = channel.empty() - ch_trimmomatic_out_log = channel.empty() - ch_trimmomatic_summary = channel.empty() - ch_cutadapt_log = channel.empty() - ch_trimgalore_log = channel.empty() - ch_trimgalore_unpaired = channel.empty() - ch_trimgalore_html = channel.empty() - ch_trimgalore_zip = channel.empty() - ch_bbduk_log = channel.empty() - ch_fastp_json = channel.empty() - ch_fastp_html = channel.empty() - ch_fastp_log = channel.empty() - ch_fastp_reads_fail = channel.empty() - ch_fastp_reads_merged = channel.empty() - ch_versions = channel.empty() + ch_reads = reads + ch_merged_reads = channel.empty() + ch_trimmomatic_unpaired_reads = channel.empty() + ch_trimmomatic_trim_log = channel.empty() + ch_trimmomatic_summary = channel.empty() + ch_trimgalore_log = channel.empty() + ch_trimgalore_unpaired = channel.empty() + ch_trimgalore_html = channel.empty() + ch_trimgalore_zip = channel.empty() + ch_fastp_html = channel.empty() + ch_fastp_log = channel.empty() + ch_fastp_reads_fail = channel.empty() + ch_adapterremoval_discarded = channel.empty() + ch_adapterremoval_paired_interleaved = channel.empty() + ch_versions = channel.empty() + ch_multiqc_files = channel.empty() if (!skip_trimmomatic) { TRIMMOMATIC( ch_reads ) ch_reads = TRIMMOMATIC.out.trimmed_reads ch_trimmomatic_unpaired_reads = TRIMMOMATIC.out.unpaired_reads ch_trimmomatic_trim_log = TRIMMOMATIC.out.trim_log - ch_trimmomatic_out_log = TRIMMOMATIC.out.out_log ch_trimmomatic_summary = TRIMMOMATIC.out.summary ch_versions = ch_versions.mix(TRIMMOMATIC.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix(TRIMMOMATIC.out.out_log) } if (!skip_cutadapt) { CUTADAPT( ch_reads ) - ch_reads = CUTADAPT.out.reads - ch_cutadapt_log = CUTADAPT.out.log - ch_versions = ch_versions.mix(CUTADAPT.out.versions.first()) + ch_reads = CUTADAPT.out.reads + ch_versions = ch_versions.mix(CUTADAPT.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix(CUTADAPT.out.log) } if (!skip_trimgalore) { @@ -76,9 +77,9 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { if (!skip_bbduk) { BBMAP_BBDUK( ch_reads, contaminants ) - ch_reads = BBMAP_BBDUK.out.reads - ch_bbduk_log = BBMAP_BBDUK.out.log - ch_versions = ch_versions.mix(BBMAP_BBDUK.out.versions.first()) + ch_reads = BBMAP_BBDUK.out.reads + ch_versions = ch_versions.mix(BBMAP_BBDUK.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix(BBMAP_BBDUK.out.log) } if (!skip_fastp) { @@ -89,27 +90,37 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { save_merged ) ch_reads = FASTP.out.reads - ch_fastp_json = FASTP.out.json + ch_merged_reads = FASTP.out.reads_merged ch_fastp_html = FASTP.out.html ch_fastp_log = FASTP.out.log ch_fastp_reads_fail = FASTP.out.reads_fail - ch_fastp_reads_merged = FASTP.out.reads_merged ch_versions = ch_versions.mix(FASTP.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix(FASTP.out.json) } -// if (!skip_adapterremoval && !do_merge) { -// ADAPTERREMOVAL( ch_reads, adapters_contaminants ) -// ch_reads.view { "DEBUG: BEFORE ADAPTERREMOVAL → $it" } -// ch_reads = ADAPTERREMOVAL.out.paired_truncated -// .mix(ADAPTERREMOVAL.out.singles_truncated) -// .map { tup -> -// def meta = tup[0] -// def r = tup[1] -// [meta, r] -// } -// ch_versions = ch_versions.mix(ADAPTERREMOVAL.out.versions) -// ch_reads.view { "DEBUG: AFTER ADAPTERREMOVAL → $it" } -// } + if (!skip_adapterremoval) { + ch_adapterremoval_in = ch_reads + .branch { meta, _reads -> + single: meta.single_end + paired: !meta.single_end + } + + ADAPTERREMOVAL_SE(ch_adapterremoval_in.single, text_adapters) + ch_versions = ch_versions.mix(ADAPTERREMOVAL_SE.out.versions.first()) + ADAPTERREMOVAL_PE(ch_adapterremoval_in.paired, text_adapters) + ch_versions = ch_versions.mix(ADAPTERREMOVAL_PE.out.versions.first()) + + ch_reads = ADAPTERREMOVAL_SE.out.singles_truncated.mix(ADAPTERREMOVAL_PE.out.paired_truncated) + ch_merged_reads = ADAPTERREMOVAL_SE.out.collapsed + .mix( + ADAPTERREMOVAL_PE.out.collapsed, + ADAPTERREMOVAL_SE.out.collapsed_truncated, + ADAPTERREMOVAL_PE.out.collapsed_truncated + ) + ch_adapterremoval_discarded = ADAPTERREMOVAL_SE.out.discarded.mix(ADAPTERREMOVAL_PE.out.discarded) + ch_adapterremoval_paired_interleaved = ADAPTERREMOVAL_SE.out.paired_interleaved.mix(ADAPTERREMOVAL_PE.out.paired_interleaved) + ch_multiqc_files = ch_multiqc_files.mix(ADAPTERREMOVAL_PE.out.settings, ADAPTERREMOVAL_SE.out.settings) + } // if (!skip_leehom && !do_merge) { // ch_reads.view { "DEBUG: BEFORE LEEHOM → $it" } @@ -146,21 +157,20 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { // } emit: - reads = ch_reads // channel: [ val(meta), [ fastq.gz ] ] - trimmomatic_unpaired_reads = ch_trimmomatic_unpaired_reads // channel: [ val(meta), [ fastq.gz ] ] - trimmomatic_trim_log = ch_trimmomatic_trim_log // channel: [ val(meta), [ log ] ] - trimmomatic_out_log = ch_trimmomatic_out_log // channel: [ val(meta), [ log ] ] - trimmomatic_summary = ch_trimmomatic_summary // channel: [ val(meta), [ summary ] ] - cutadapt_log = ch_cutadapt_log // channel: [ val(meta), [ log ] ] - trimgalore_log = ch_trimgalore_log // channel: [ val(meta), [ txt ] ] - trimgalore_unpaired = ch_trimgalore_unpaired // channel: [ val(meta), [ fq.gz ] ] - trimgalore_html = ch_trimgalore_html // channel: [ val(meta), [ html ] ] - trimgalore_zip = ch_trimgalore_zip // channel: [ val(meta), [ zip ] ] - bbduk_log = ch_bbduk_log // channel: [ val(meta), [ log ] ] - fastp_json = ch_fastp_json // channel: [ val(meta), [ json ] ] - fastp_html = ch_fastp_html // channel: [ val(meta), [ html ] ] - fastp_log = ch_fastp_log // channel: [ val(meta), [ log ] ] - fastp_reads_fail = ch_fastp_reads_fail // channel: [ val(meta), [ fastq.gz ] ] - fastp_reads_merged = ch_fastp_reads_merged // channel: [ val(meta), [ fastq.gz ] ] - versions = ch_versions // channel: [ versions.yml ] + reads = ch_reads // channel: [ val(meta), [ fastq.gz ] ] + merged_reads = ch_merged_reads // channel: [ val(meta), [ fastq.gz ] ] + trimmomatic_unpaired_reads = ch_trimmomatic_unpaired_reads // channel: [ val(meta), [ fastq.gz ] ] + trimmomatic_trim_log = ch_trimmomatic_trim_log // channel: [ val(meta), [ log ] ] + trimmomatic_summary = ch_trimmomatic_summary // channel: [ val(meta), [ summary ] ] + trimgalore_log = ch_trimgalore_log // channel: [ val(meta), [ txt ] ] + trimgalore_unpaired = ch_trimgalore_unpaired // channel: [ val(meta), [ fq.gz ] ] + trimgalore_html = ch_trimgalore_html // channel: [ val(meta), [ html ] ] + trimgalore_zip = ch_trimgalore_zip // channel: [ val(meta), [ zip ] ] + fastp_html = ch_fastp_html // channel: [ val(meta), [ html ] ] + fastp_log = ch_fastp_log // channel: [ val(meta), [ log ] ] + fastp_reads_fail = ch_fastp_reads_fail // channel: [ val(meta), [ fastq.gz ] ] + adapterremoval_discarded = ch_adapterremoval_discarded // channel: [ val(meta), [ fastq.gz ] ] + adapterremoval_paired_interleaved = ch_adapterremoval_paired_interleaved // channel: [ val(meta), [ fastq.gz ] ] + versions = ch_versions // channel: [ versions.yml ] + multiqc_files = ch_multiqc_files } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml index 2347a1cc99e9..f8eb33d7112a 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml +++ b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml @@ -13,6 +13,7 @@ components: - trimgalore - bbmap/bbduk - fastp + - adapterremoval input: - ch_reads: type: file @@ -60,11 +61,26 @@ input: description: | Specify true to save all merged reads to a file ending in `*.merged.fastq.gz` Used by fastp + - skip_adapterremoval: + type: boolean + description: | + If true, skips the adapterremoval process. + - text_adapters: + type: file + description: Optional text file containing list of adapters to look for for removal + with one adapter per line. Otherwise will look for default adapters (see AdapterRemoval + man page), or can be modified to remove user-specified adapters via ext.args. output: - reads: type: file description: The trimmed/modified single or paired end fastq reads pattern: "*.fastq.gz" + - merged_reads: + type: file + description: | + The trimmed/modified fastq reads merged into a single file. + Only meaningful for paired-end reads. + pattern: "*.fastq.gz" - trimmomatic_unpaired_reads: type: file description: The trimmed/modified unpaired end fastq reads @@ -73,18 +89,10 @@ output: type: file description: trimmomatic log file, from the trim_log parameter pattern: "*.log" - - trimmomatic_out_log: - type: file - description: log of output from the standard out - pattern: "*.log" - trimmomatic_summary: type: file description: trimmomatic summary file of surviving and dropped reads pattern: "*.summary" - - cutadapt_log: - type: file - description: cuatadapt log file - pattern: "*cutadapt.log" - trimgalore_log: type: file description: | @@ -105,14 +113,6 @@ output: description: | fastqc zip output if run with the --fastqc flag. pattern: "*_fastqc.zip" - - bbduk_log: - type: file - description: Bbduk log file - pattern: "*bbduk.log" - - fastp_json: - type: file - description: fastp results in JSON format - pattern: "*.json" - fastp_html: type: file description: fastp results in HTML format @@ -125,16 +125,26 @@ output: type: file description: fastp reads that failed the preprocessing pattern: "*fail.fastq.gz" - - fastp_reads_merged: + - adapterremoval_discarded: type: file - description: fastp reads that were successfully merged - pattern: "*.merged.fastq.gz" + description: | + Adapter trimmed FastQ files of reads that did not pass filtering + thresholds. + pattern: "*.discarded.fastq.gz" + - adapterremoval_paired_interleaved: + type: file + description: | + Write paired-end reads to a single file, interleaving mate 1 and mate 2 reads + pattern: "*.paired.fastq.gz" - versions: type: file description: | File containing software versions Structure: [ path(versions.yml) ] pattern: "versions.yml" + - multiqc_files: + type: file + description: MultiQC-compatible output files from tools used in preprocessing authors: - "@kornkv" - "@vagkaratzas" diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index f496f291e474..4b77689f7ddc 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -14,13 +14,17 @@ nextflow_workflow { tag "bbmap" tag "bbmap/bbduk" tag "fastp" - // tag "adapterremoval" + tag "adapterremoval" // tag "leehom" // tag "ngmerge" test("sarscov2 - fastq - single-end") { config "./nextflow_SE.config" when { + params { + save_merged = false + adapterremoval_args = save_merged ? "--collapse" : "" + } workflow { """ input[0] = [ @@ -28,18 +32,19 @@ nextflow_workflow { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] - input[1] = false // skip_trimmomatic - input[2] = false // skip_cutadapt - input[3] = false // skip_trimgalore - input[4] = false // skip_bbduk - input[5] = [] // contaminants - input[6] = false // skip_fastp - input[7] = false // fastp_discard_trimmed_pass - input[8] = true // fastp_save_trimmed_fail - input[9] = true // save_merged - // input[10] = false // skip_adapterremoval - // input[11] = false // skip_leehom - // input[12] = true // skip_ngmerge + input[1] = false // skip_trimmomatic + input[2] = false // skip_cutadapt + input[3] = false // skip_trimgalore + input[4] = false // skip_bbduk + input[5] = [] // contaminants + input[6] = false // skip_fastp + input[7] = false // fastp_discard_trimmed_pass + input[8] = true // fastp_save_trimmed_fail + input[9] = params.save_merged + input[10] = false // skip_adapterremoval + input[11] = [] // text adapters + // input[12] = false // skip_leehom + // input[13] = true // skip_ngmerge """ } } @@ -49,15 +54,13 @@ nextflow_workflow { assert snapshot( workflow.out.reads[0][1], workflow.out.trimmomatic_trim_log[0][1], - file(workflow.out.trimmomatic_out_log[0][1]).name, workflow.out.trimmomatic_summary[0][1], - workflow.out.cutadapt_log[0][1], path(workflow.out.trimgalore_log[0][1]).readLines().size(), - path(workflow.out.bbduk_log[0][1]).readLines().size(), - workflow.out.fastp_json[0][1], file(workflow.out.fastp_html[0][1]).name, path(workflow.out.fastp_log[0][1]).readLines().size(), workflow.out.fastp_reads_fail[0][1], + file(workflow.out.adapterremoval_discarded[0][1]).name, + file(workflow.out.multiqc_files[0][1]).name, workflow.out.versions.collect { path(it).yaml } ).match() } @@ -66,6 +69,10 @@ nextflow_workflow { test("sarscov2 - fastq - paired-end") { config "./nextflow_PE.config" when { + params { + save_merged = true + adapterremoval_args = save_merged ? "--collapse" : "" + } workflow { """ input[0] = [ @@ -76,18 +83,19 @@ nextflow_workflow { ] ] - input[1] = false // skip_trimmomatic - input[2] = false // skip_cutadapt - input[3] = false // skip_trimgalore - input[4] = false // skip_bbduk - input[5] = [] // contaminants - input[6] = false // skip_fastp - input[7] = false // fastp_discard_trimmed_pass - input[8] = true // fastp_save_trimmed_fail - input[9] = true // save_merged - // input[10] = false // skip_adapterremoval - // input[11] = false // skip_leehom - // input[12] = true // skip_ngmerge + input[1] = false // skip_trimmomatic + input[2] = false // skip_cutadapt + input[3] = false // skip_trimgalore + input[4] = false // skip_bbduk + input[5] = [] // contaminants + input[6] = false // skip_fastp + input[7] = false // fastp_discard_trimmed_pass + input[8] = true // fastp_save_trimmed_fail + input[9] = params.save_merged + input[10] = false // skip_adapterremoval + input[11] = [] // text adapters + // input[12] = false // skip_leehom + // input[13] = true // skip_ngmerge """ } } @@ -96,18 +104,17 @@ nextflow_workflow { assert workflow.success assert snapshot( workflow.out.reads[0][1], + workflow.out.merged_reads[0][1], // merged reads workflow.out.trimmomatic_unpaired_reads[0][1], workflow.out.trimmomatic_trim_log[0][1], - file(workflow.out.trimmomatic_out_log[0][1]).name, workflow.out.trimmomatic_summary[0][1], - workflow.out.cutadapt_log[0][1], path(workflow.out.trimgalore_log[0][1][0]).readLines().size(), path(workflow.out.trimgalore_log[0][1][1]).readLines().size(), - path(workflow.out.bbduk_log[0][1]).readLines().size(), - workflow.out.fastp_json[0][1], file(workflow.out.fastp_html[0][1]).name, path(workflow.out.fastp_log[0][1]).readLines().size(), workflow.out.fastp_reads_fail[0][1].collect { file(it).name }.sort(), + file(workflow.out.adapterremoval_discarded[0][1]).name, + file(workflow.out.multiqc_files[0][1]).name, workflow.out.versions.collect { path(it).yaml } ).match() } @@ -146,6 +153,7 @@ nextflow_workflow { // then { // assertAll( // { assert workflow.success }, + // workflow.out.adapterremoval_collapsed[0][1], // { assert snapshot(workflow.out).match() } // ) // } @@ -156,6 +164,10 @@ nextflow_workflow { options "-stub" when { + params { + save_merged = false + adapterremoval_args = save_merged ? "--collapse" : "" + } workflow { """ input[0] = [ @@ -163,18 +175,19 @@ nextflow_workflow { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] - input[1] = false // skip_trimmomatic - input[2] = true // skip_cutadapt - input[3] = false // skip_trimgalore - input[4] = false // skip_bbduk - input[5] = [] // contaminants - input[6] = false // skip_fastp - input[7] = false // fastp_discard_trimmed_pass - input[8] = true // fastp_save_trimmed_fail - input[9] = true // save_merged - // input[10] = false // skip_adapterremoval - // input[11] = false // skip_leehom - // input[12] = true // skip_ngmerge + input[1] = false // skip_trimmomatic + input[2] = true // skip_cutadapt + input[3] = false // skip_trimgalore + input[4] = false // skip_bbduk + input[5] = [] // contaminants + input[6] = false // skip_fastp + input[7] = false // fastp_discard_trimmed_pass + input[8] = true // fastp_save_trimmed_fail + input[9] = params.save_merged + input[10] = false // skip_adapterremoval + input[11] = [] // text adapters + // input[12] = false // skip_leehom + // input[13] = true // skip_ngmerge """ } } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap index be1380c7ff44..4d8b7db4c6f7 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap @@ -8,7 +8,7 @@ "id": "test", "single_end": true }, - "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test.truncated.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "1": [ @@ -20,7 +20,7 @@ "id": "test", "single_end": true }, - "test.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "11": [ @@ -29,7 +29,7 @@ "id": "test", "single_end": true }, - "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "12": [ @@ -38,44 +38,51 @@ "id": "test", "single_end": true }, - "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.discarded.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "13": [ + + ], + "14": [ + "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", + "versions.yml:md5,2d5c9b99267e97292e2a581635bd72f7", + "versions.yml:md5,aa418419664a944b74696ee0e9ef1c7a", + "versions.yml:md5,bcfe22d952cc3ae0ac5ff685e16fa4a5", + "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" + ], + "15": [ [ { "id": "test", "single_end": true }, - "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "14": [ + "test.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ], [ { "id": "test", "single_end": true }, - "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "15": [ - - ], - "16": [ - "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", - "versions.yml:md5,2d5c9b99267e97292e2a581635bd72f7", - "versions.yml:md5,bcfe22d952cc3ae0ac5ff685e16fa4a5", - "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" - ], - "2": [ + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ], [ { "id": "test", "single_end": true }, - "test_trim.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.settings:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test", + "single_end": true + }, + "test_out.log:md5,d41d8cd98f00b204e9800998ecf8427e" ] + ], + "2": [ + ], "3": [ [ @@ -83,7 +90,7 @@ "id": "test", "single_end": true }, - "test_out.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test_trim.log:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "4": [ @@ -96,9 +103,6 @@ ] ], "5": [ - - ], - "6": [ [ { "id": "test", @@ -106,6 +110,9 @@ }, "test.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] + ], + "6": [ + ], "7": [ @@ -114,36 +121,33 @@ ], "9": [ - - ], - "bbduk_log": [ [ { "id": "test", "single_end": true }, - "test.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "cutadapt_log": [ - - ], - "fastp_html": [ + "adapterremoval_discarded": [ [ { "id": "test", "single_end": true }, - "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.discarded.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "fastp_json": [ + "adapterremoval_paired_interleaved": [ + + ], + "fastp_html": [ [ { "id": "test", "single_end": true }, - "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "fastp_log": [ @@ -164,8 +168,38 @@ "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "fastp_reads_merged": [ + "merged_reads": [ + ], + "multiqc_files": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test", + "single_end": true + }, + "test.settings:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test", + "single_end": true + }, + "test_out.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ], "reads": [ [ @@ -173,7 +207,7 @@ "id": "test", "single_end": true }, - "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test.truncated.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "trimgalore_html": [ @@ -193,15 +227,6 @@ ], "trimgalore_zip": [ - ], - "trimmomatic_out_log": [ - [ - { - "id": "test", - "single_end": true - }, - "test_out.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] ], "trimmomatic_summary": [ [ @@ -227,6 +252,7 @@ "versions": [ "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", "versions.yml:md5,2d5c9b99267e97292e2a581635bd72f7", + "versions.yml:md5,aa418419664a944b74696ee0e9ef1c7a", "versions.yml:md5,bcfe22d952cc3ae0ac5ff685e16fa4a5", "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" ] @@ -236,26 +262,23 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T19:38:21.971691897" + "timestamp": "2025-12-09T11:14:22.599187687" }, "sarscov2 - fastq - paired-end": { "content": [ [ - "test_1.fastp.fastq.gz:md5,ced67d85f7936c54e13822d3dba061c8", - "test_2.fastp.fastq.gz:md5,4d8b08322b9cbaf6258db35726f2c658" + "test.pair1.truncated.fastq.gz:md5,b2f0ff871e44ccb66bb948524503d4d3", + "test.pair2.truncated.fastq.gz:md5,3a13402b3f1ac1462d10da45c9829444" ], + "test.collapsed.fastq.gz:md5,909e9abf6cdfcd32508582dc2768854a", [ "test.unpaired.trim_1.fastq.gz:md5,f22935d14248bd936af8d5e3c27e72b2", "test.unpaired.trim_2.fastq.gz:md5,ce0d8e849e4677a186cd0566b2a6ea15" ], "test_trim.log:md5,9629761761a34576b3484bf4174f681f", - "test_out.log", "test.summary:md5,9698e5e5c060bbe64588998fe35f8d71", - "test.cutadapt.log:md5,8da32e029f7c4b891930cc656abea887", 60, 63, - 21, - "test.fastp.json:md5,5cfafac26b0bcec71a2022276904d975", "test.fastp.html", 51, [ @@ -263,7 +286,14 @@ "test_1.fail.fastq.gz", "test_2.fail.fastq.gz" ], + "test.discarded.fastq.gz", + "test.bbduk.log", [ + { + "FASTQ_REMOVEADAPTERS_MERGE:ADAPTERREMOVAL_PE": { + "adapterremoval": "2.3.2" + } + }, { "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { "trimgalore": "0.6.10", @@ -297,21 +327,19 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T19:58:49.88448508" + "timestamp": "2025-12-09T11:28:02.942964155" }, "sarscov2 - fastq - single-end": { "content": [ - "test.fastp.fastq.gz:md5,84aa1ce965cafc4a59aabeb986f1e325", + "test.truncated.fastq.gz:md5,151f9ca2bfb8c52579884fa7c4d6d9f9", "test_trim.log:md5,e4c3f619e9b0e26847f8f3e3d9af319b", - "test_out.log", "test.summary:md5,24c973237557a1439c775ca19a5deaa5", - "test.cutadapt.log:md5,7cbd396c162d74ec27ae2f88834b5685", 61, - 21, - "test.fastp.json:md5,f1e9b92d4c11419310aee353bf048ec0", "test.fastp.html", 32, "test.fail.fastq.gz:md5,3e4aaadb66a5b8fc9b881bf39c227abd", + "test.discarded.fastq.gz", + "test.bbduk.log", [ { "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { @@ -325,6 +353,11 @@ "fastp": "1.0.1" } }, + { + "FASTQ_REMOVEADAPTERS_MERGE:ADAPTERREMOVAL_SE": { + "adapterremoval": "2.3.2" + } + }, { "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { "bbmap": 39.18 @@ -346,6 +379,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-08T19:48:31.272945778" + "timestamp": "2025-12-09T11:27:46.873445297" } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config index ebd460bf9ecf..e1badf49b21a 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow.config @@ -1,10 +1,9 @@ process { - withName: CUTADAPT { + withName: 'CUTADAPT' { ext.args = '-q 25' } - withName: BBMAP_BBDUK { + withName: 'BBMAP_BBDUK' { ext.args = 'trimq=10 qtrim=r' } - } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_PE.config b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_PE.config index 3f8fdfe1125e..dc4eef5d6025 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_PE.config +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_PE.config @@ -1,6 +1,9 @@ process { - - withName: TRIMMOMATIC { + withName: 'TRIMMOMATIC' { ext.args = 'ILLUMINACLIP:TruSeq3-PE.fa:2:30:10 LEADING:3 TRAILING:3 SLIDINGWINDOW:4:15 MINLEN:36' } + + withName: 'ADAPTERREMOVAL_PE' { + ext.args = params.adapterremoval_args + } } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_SE.config b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_SE.config index af777fda0427..82c186711dab 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_SE.config +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/nextflow_SE.config @@ -1,6 +1,9 @@ process { - - withName: TRIMMOMATIC { + withName: 'TRIMMOMATIC' { ext.args = 'ILLUMINACLIP:TruSeq3-SE:2:30:10 LEADING:3 TRAILING:3 SLIDINGWINDOW:4:15 MINLEN:36' } + + withName: 'ADAPTERREMOVAL_SE' { + ext.args = params.adapterremoval_args + } } From 209581deff6d14d337bbbf0a7a9897fa2bc59310 Mon Sep 17 00:00:00 2001 From: Evangelos Karatzas <32259775+vagkaratzas@users.noreply.github.com> Date: Tue, 9 Dec 2025 13:57:08 +0000 Subject: [PATCH 35/83] leehom checkpoint (#9534) * leehom checkpoint * debugged with transpose and proper collect on nf-test * leehom change order --- .../fastq_removeadapters_merge/main.nf | 80 +++------ .../fastq_removeadapters_merge/meta.yml | 27 +-- .../tests/main.nf.test | 134 +++++++------- .../tests/main.nf.test.snap | 168 +++++++++++------- 4 files changed, 209 insertions(+), 200 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index 9d6560aef052..14588aa27869 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -3,11 +3,12 @@ include { TRIMMOMATIC } from '../../../modules/nf-core/t include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' // both SE and PE include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' // both SE and PE include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' // both SE and PE +include { LEEHOM } from '../../../modules/nf-core/leehom/main' // both SE and PE // // allows merging of paired end reads, but will work for single end reads as well include { FASTP } from '../../../modules/nf-core/fastp/main' // both SE and PE + merge -include { ADAPTERREMOVAL as ADAPTERREMOVAL_SE } from '../../../modules/nf-core/adapterremoval/main' +include { ADAPTERREMOVAL as ADAPTERREMOVAL_SE } from '../../../modules/nf-core/adapterremoval/main' // both SE and PE + merge include { ADAPTERREMOVAL as ADAPTERREMOVAL_PE } from '../../../modules/nf-core/adapterremoval/main' -// include { LEEHOM } from '../../../modules/nf-core/leehom/main' + // // requires paired end because of merging // include { NGMERGE } from '../../../modules/nf-core/ngmerge/main' @@ -20,30 +21,27 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { skip_trimgalore // boolean skip_bbduk // boolean contaminants // channel: [ reads ] // fasta, adapters to remove + skip_leehom // boolean skip_fastp // boolean fastp_discard_trimmed_pass // boolean fastp_save_trimmed_fail // boolean save_merged // boolean skip_adapterremoval // boolean text_adapters // channel: [ txt ] // adapters to remove, in adapterremoval text format - // skip_leehom // boolean // skip_ngmerge // boolean main: ch_reads = reads ch_merged_reads = channel.empty() - ch_trimmomatic_unpaired_reads = channel.empty() + ch_discarded_reads = channel.empty() ch_trimmomatic_trim_log = channel.empty() ch_trimmomatic_summary = channel.empty() ch_trimgalore_log = channel.empty() - ch_trimgalore_unpaired = channel.empty() ch_trimgalore_html = channel.empty() ch_trimgalore_zip = channel.empty() ch_fastp_html = channel.empty() ch_fastp_log = channel.empty() - ch_fastp_reads_fail = channel.empty() - ch_adapterremoval_discarded = channel.empty() ch_adapterremoval_paired_interleaved = channel.empty() ch_versions = channel.empty() ch_multiqc_files = channel.empty() @@ -51,7 +49,7 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { if (!skip_trimmomatic) { TRIMMOMATIC( ch_reads ) ch_reads = TRIMMOMATIC.out.trimmed_reads - ch_trimmomatic_unpaired_reads = TRIMMOMATIC.out.unpaired_reads + ch_discarded_reads = ch_discarded_reads.mix(TRIMMOMATIC.out.unpaired_reads.transpose()) // .transpose() because paired reads have 2 unpaired files in an array ch_trimmomatic_trim_log = TRIMMOMATIC.out.trim_log ch_trimmomatic_summary = TRIMMOMATIC.out.summary ch_versions = ch_versions.mix(TRIMMOMATIC.out.versions.first()) @@ -68,8 +66,8 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { if (!skip_trimgalore) { TRIMGALORE( ch_reads ) ch_reads = TRIMGALORE.out.reads + ch_discarded_reads = ch_discarded_reads.mix(TRIMGALORE.out.unpaired) ch_trimgalore_log = TRIMGALORE.out.log - ch_trimgalore_unpaired = TRIMGALORE.out.unpaired ch_trimgalore_html = TRIMGALORE.out.html ch_trimgalore_zip = TRIMGALORE.out.zip ch_versions = ch_versions.mix(TRIMGALORE.out.versions.first()) @@ -82,6 +80,24 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { ch_multiqc_files = ch_multiqc_files.mix(BBMAP_BBDUK.out.log) } + if (!skip_leehom) { + LEEHOM(ch_reads) + + ch_reads = LEEHOM.out.fq_pass + .join(LEEHOM.out.unmerged_r1_fq_pass, by: 0, remainder: true) + .join(LEEHOM.out.unmerged_r2_fq_pass, by: 0, remainder: true) + .map { meta, single, r1, r2 -> + if (meta.single_end) { + return [meta, single] + } else { + return [meta, [r1, r2]] + } + } + ch_discarded_reads = ch_discarded_reads.mix(LEEHOM.out.fq_fail, LEEHOM.out.unmerged_r1_fq_fail, LEEHOM.out.unmerged_r2_fq_fail) + ch_versions = ch_versions.mix(LEEHOM.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix(LEEHOM.out.log) + } + if (!skip_fastp) { FASTP( ch_reads.map { meta, files -> [ meta, files, contaminants ] }, @@ -91,9 +107,9 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { ) ch_reads = FASTP.out.reads ch_merged_reads = FASTP.out.reads_merged + ch_discarded_reads = ch_discarded_reads.mix(FASTP.out.reads_fail.transpose()) // .transpose() because paired reads have 3 fail files in an array ch_fastp_html = FASTP.out.html ch_fastp_log = FASTP.out.log - ch_fastp_reads_fail = FASTP.out.reads_fail ch_versions = ch_versions.mix(FASTP.out.versions.first()) ch_multiqc_files = ch_multiqc_files.mix(FASTP.out.json) } @@ -106,9 +122,7 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { } ADAPTERREMOVAL_SE(ch_adapterremoval_in.single, text_adapters) - ch_versions = ch_versions.mix(ADAPTERREMOVAL_SE.out.versions.first()) ADAPTERREMOVAL_PE(ch_adapterremoval_in.paired, text_adapters) - ch_versions = ch_versions.mix(ADAPTERREMOVAL_PE.out.versions.first()) ch_reads = ADAPTERREMOVAL_SE.out.singles_truncated.mix(ADAPTERREMOVAL_PE.out.paired_truncated) ch_merged_reads = ADAPTERREMOVAL_SE.out.collapsed @@ -117,59 +131,23 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { ADAPTERREMOVAL_SE.out.collapsed_truncated, ADAPTERREMOVAL_PE.out.collapsed_truncated ) - ch_adapterremoval_discarded = ADAPTERREMOVAL_SE.out.discarded.mix(ADAPTERREMOVAL_PE.out.discarded) + ch_discarded_reads = ch_discarded_reads.mix(ADAPTERREMOVAL_SE.out.discarded, ADAPTERREMOVAL_PE.out.discarded) ch_adapterremoval_paired_interleaved = ADAPTERREMOVAL_SE.out.paired_interleaved.mix(ADAPTERREMOVAL_PE.out.paired_interleaved) + ch_versions = ch_versions.mix(ADAPTERREMOVAL_SE.out.versions.first(), ADAPTERREMOVAL_PE.out.versions.first()) ch_multiqc_files = ch_multiqc_files.mix(ADAPTERREMOVAL_PE.out.settings, ADAPTERREMOVAL_SE.out.settings) } -// if (!skip_leehom && !do_merge) { -// ch_reads.view { "DEBUG: BEFORE LEEHOM → $it" } -// ch_leehom_input = ch_reads.map { meta, r -> -// if (meta.single_end) -// return [meta, r] -// else -// return [meta, [reads[0], reads[1]]] -// } - -// LEEHOM(ch_leehom_input) - -// ch_leehom_pe = -// LEEHOM.out.unmerged_r1_fq_pass -// .combine(LEEHOM.out.unmerged_r2_fq_pass) -// .map { left, right -> -// def meta = left[0] -// def r1 = left[1] -// def r2 = right[1] -// [meta, [r1, r2]] -// } -// .filter { meta, r -> !meta.single_end } // only PE - -// // ---- SE OUTPUT ---- -// ch_leehom_se = -// LEEHOM.out.fq_pass -// .filter { meta, r -> meta.single_end } -// .map { meta, r -> [meta, r] } - -// // ---- MERGE CHANNELS ---- -// ch_reads = ch_leehom_pe.mix(ch_leehom_se) - -// ch_versions = ch_versions.mix(LEEHOM.out.versions) -// } - emit: reads = ch_reads // channel: [ val(meta), [ fastq.gz ] ] merged_reads = ch_merged_reads // channel: [ val(meta), [ fastq.gz ] ] - trimmomatic_unpaired_reads = ch_trimmomatic_unpaired_reads // channel: [ val(meta), [ fastq.gz ] ] + discarded_reads = ch_discarded_reads // channel: [ val(meta), [ fastq.gz ] ] trimmomatic_trim_log = ch_trimmomatic_trim_log // channel: [ val(meta), [ log ] ] trimmomatic_summary = ch_trimmomatic_summary // channel: [ val(meta), [ summary ] ] trimgalore_log = ch_trimgalore_log // channel: [ val(meta), [ txt ] ] - trimgalore_unpaired = ch_trimgalore_unpaired // channel: [ val(meta), [ fq.gz ] ] trimgalore_html = ch_trimgalore_html // channel: [ val(meta), [ html ] ] trimgalore_zip = ch_trimgalore_zip // channel: [ val(meta), [ zip ] ] fastp_html = ch_fastp_html // channel: [ val(meta), [ html ] ] fastp_log = ch_fastp_log // channel: [ val(meta), [ log ] ] - fastp_reads_fail = ch_fastp_reads_fail // channel: [ val(meta), [ fastq.gz ] ] - adapterremoval_discarded = ch_adapterremoval_discarded // channel: [ val(meta), [ fastq.gz ] ] adapterremoval_paired_interleaved = ch_adapterremoval_paired_interleaved // channel: [ val(meta), [ fastq.gz ] ] versions = ch_versions // channel: [ versions.yml ] multiqc_files = ch_multiqc_files diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml index f8eb33d7112a..1012d6ce1120 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml +++ b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml @@ -12,6 +12,7 @@ components: - cutadapt - trimgalore - bbmap/bbduk + - leehom - fastp - adapterremoval input: @@ -42,6 +43,10 @@ input: type: file description: | Reference files used by bbmap/bbduk and/or fastp, containing adapter and/or contaminant sequences for removal + - skip_leehom: + type: boolean + description: | + If true, skips the leehom process. - skip_fastp: type: boolean description: | @@ -81,10 +86,11 @@ output: The trimmed/modified fastq reads merged into a single file. Only meaningful for paired-end reads. pattern: "*.fastq.gz" - - trimmomatic_unpaired_reads: + - discarded_reads: type: file - description: The trimmed/modified unpaired end fastq reads - pattern: "*.unpaired.trim_*.fastq.gz" + description: | + All files containing discarded reads throughout the steps. + pattern: "*.fastq.gz" - trimmomatic_trim_log: type: file description: trimmomatic log file, from the trim_log parameter @@ -98,11 +104,6 @@ output: description: | trimgalore log file pattern: "*_report.txt" - - trimgalore_unpaired: - type: file - description: | - Unpaired trimgalore reads. Activate with the --retain_unpaired flag. - pattern: "*unpaired*.fq.gz" - trimgalore_html: type: file description: | @@ -121,16 +122,6 @@ output: type: file description: fastp fastq log file pattern: "*.log" - - fastp_reads_fail: - type: file - description: fastp reads that failed the preprocessing - pattern: "*fail.fastq.gz" - - adapterremoval_discarded: - type: file - description: | - Adapter trimmed FastQ files of reads that did not pass filtering - thresholds. - pattern: "*.discarded.fastq.gz" - adapterremoval_paired_interleaved: type: file description: | diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index 4b77689f7ddc..a5dafcee3aee 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -13,9 +13,9 @@ nextflow_workflow { tag "trimgalore" tag "bbmap" tag "bbmap/bbduk" + tag "leehom" tag "fastp" tag "adapterremoval" - // tag "leehom" // tag "ngmerge" test("sarscov2 - fastq - single-end") { @@ -37,13 +37,13 @@ nextflow_workflow { input[3] = false // skip_trimgalore input[4] = false // skip_bbduk input[5] = [] // contaminants - input[6] = false // skip_fastp - input[7] = false // fastp_discard_trimmed_pass - input[8] = true // fastp_save_trimmed_fail - input[9] = params.save_merged - input[10] = false // skip_adapterremoval - input[11] = [] // text adapters - // input[12] = false // skip_leehom + input[6] = false // skip_leehom + input[7] = false // skip_fastp + input[8] = false // fastp_discard_trimmed_pass + input[9] = true // fastp_save_trimmed_fail + input[10] = params.save_merged + input[11] = false // skip_adapterremoval + input[12] = [] // text adapters // input[13] = true // skip_ngmerge """ } @@ -53,14 +53,13 @@ nextflow_workflow { assert workflow.success assert snapshot( workflow.out.reads[0][1], + workflow.out.discarded_reads.collect { file(it[1]).name }, workflow.out.trimmomatic_trim_log[0][1], workflow.out.trimmomatic_summary[0][1], path(workflow.out.trimgalore_log[0][1]).readLines().size(), file(workflow.out.fastp_html[0][1]).name, path(workflow.out.fastp_log[0][1]).readLines().size(), - workflow.out.fastp_reads_fail[0][1], - file(workflow.out.adapterremoval_discarded[0][1]).name, - file(workflow.out.multiqc_files[0][1]).name, + workflow.out.multiqc_files.collect { file(it[1]).name }, workflow.out.versions.collect { path(it).yaml } ).match() } @@ -88,13 +87,13 @@ nextflow_workflow { input[3] = false // skip_trimgalore input[4] = false // skip_bbduk input[5] = [] // contaminants - input[6] = false // skip_fastp - input[7] = false // fastp_discard_trimmed_pass - input[8] = true // fastp_save_trimmed_fail - input[9] = params.save_merged - input[10] = false // skip_adapterremoval - input[11] = [] // text adapters - // input[12] = false // skip_leehom + input[6] = false // skip_leehom + input[7] = false // skip_fastp + input[8] = false // fastp_discard_trimmed_pass + input[9] = true // fastp_save_trimmed_fail + input[10] = params.save_merged + input[11] = false // skip_adapterremoval + input[12] = [] // text adapters // input[13] = true // skip_ngmerge """ } @@ -104,60 +103,59 @@ nextflow_workflow { assert workflow.success assert snapshot( workflow.out.reads[0][1], - workflow.out.merged_reads[0][1], // merged reads - workflow.out.trimmomatic_unpaired_reads[0][1], + workflow.out.merged_reads[0][1], + workflow.out.discarded_reads.collect { file(it[1]).name }, workflow.out.trimmomatic_trim_log[0][1], workflow.out.trimmomatic_summary[0][1], path(workflow.out.trimgalore_log[0][1][0]).readLines().size(), path(workflow.out.trimgalore_log[0][1][1]).readLines().size(), file(workflow.out.fastp_html[0][1]).name, path(workflow.out.fastp_log[0][1]).readLines().size(), - workflow.out.fastp_reads_fail[0][1].collect { file(it).name }.sort(), - file(workflow.out.adapterremoval_discarded[0][1]).name, - file(workflow.out.multiqc_files[0][1]).name, + workflow.out.multiqc_files.collect { file(it[1]).name }, workflow.out.versions.collect { path(it).yaml } ).match() } } - // test("sarscov2 - fastq - paired-end, no merging") { - // when { params { - // samtools_arg = '' - // } - // workflow { - // """ - // input[0] = [ - // [ id:'test_paired', single_end:false ], - // [ - // file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - // file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) - // ] - // ] - - // input[1] = false // skip_trimmomatic - // input[2] = false // skip_cutadapt - // input[3] = false // skip_trimgalore - // input[4] = false // skip_bbduk - // input[5] = [] // contaminants - // input[6] = false // skip_fastp - // input[7] = false // fastp_discard_trimmed_pass - // input[8] = true // fastp_save_trimmed_fail - // input[9] = true // save_merged - // input[10] = false // skip_adapterremoval - // input[11] = false // skip_leehom - // input[12] = true // skip_ngmerge - // """ - // } - // } - - // then { - // assertAll( - // { assert workflow.success }, - // workflow.out.adapterremoval_collapsed[0][1], - // { assert snapshot(workflow.out).match() } - // ) - // } - // } + // // test("sarscov2 - fastq - paired-end, no merging") { + // // when { params { + // // samtools_arg = '' + // // } + // // workflow { + // // """ + // // input[0] = [ + // // [ id:'test_paired', single_end:false ], + // // [ + // // file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + // // file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + // // ] + // // ] + + // // input[1] = false // skip_trimmomatic + // // input[2] = false // skip_cutadapt + // // input[3] = false // skip_trimgalore + // // input[4] = false // skip_bbduk + // // input[5] = [] // contaminants + // input[6] = false // skip_leehom + // input[7] = false // skip_fastp + // input[8] = false // fastp_discard_trimmed_pass + // input[9] = true // fastp_save_trimmed_fail + // input[10] = params.save_merged + // input[11] = false // skip_adapterremoval + // input[12] = [] // text adapters + // // input[13] = true // skip_ngmerge + // // """ + // // } + // // } + + // // then { + // // assertAll( + // // { assert workflow.success }, + // // workflow.out.adapterremoval_collapsed[0][1], + // // { assert snapshot(workflow.out).match() } + // // ) + // // } + // // } test("sarscov2 - fastq - single-end - stub") { @@ -180,13 +178,13 @@ nextflow_workflow { input[3] = false // skip_trimgalore input[4] = false // skip_bbduk input[5] = [] // contaminants - input[6] = false // skip_fastp - input[7] = false // fastp_discard_trimmed_pass - input[8] = true // fastp_save_trimmed_fail - input[9] = params.save_merged - input[10] = false // skip_adapterremoval - input[11] = [] // text adapters - // input[12] = false // skip_leehom + input[6] = false // skip_leehom + input[7] = false // skip_fastp + input[8] = false // fastp_discard_trimmed_pass + input[9] = true // fastp_save_trimmed_fail + input[10] = params.save_merged + input[11] = false // skip_adapterremoval + input[12] = [] // text adapters // input[13] = true // skip_ngmerge """ } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap index 4d8b7db4c6f7..690cf8aa97c3 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap @@ -15,74 +15,75 @@ ], "10": [ + + ], + "11": [ + "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", + "versions.yml:md5,2d5c9b99267e97292e2a581635bd72f7", + "versions.yml:md5,aa418419664a944b74696ee0e9ef1c7a", + "versions.yml:md5,ba074f9db361b3f8d0a8cc93c3907a91", + "versions.yml:md5,bcfe22d952cc3ae0ac5ff685e16fa4a5", + "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" + ], + "12": [ [ { "id": "test", "single_end": true }, - "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "11": [ + "test.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ], [ { "id": "test", "single_end": true }, - "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "12": [ + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ], [ { "id": "test", "single_end": true }, - "test.discarded.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "13": [ - - ], - "14": [ - "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", - "versions.yml:md5,2d5c9b99267e97292e2a581635bd72f7", - "versions.yml:md5,aa418419664a944b74696ee0e9ef1c7a", - "versions.yml:md5,bcfe22d952cc3ae0ac5ff685e16fa4a5", - "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" - ], - "15": [ + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ], [ { "id": "test", "single_end": true }, - "test.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.settings:md5,d41d8cd98f00b204e9800998ecf8427e" ], [ { "id": "test", "single_end": true }, - "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + "test_out.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.discarded.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ], [ { "id": "test", "single_end": true }, - "test.settings:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ], [ { "id": "test", "single_end": true }, - "test_out.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.fail.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] - ], - "2": [ - ], "3": [ [ @@ -118,9 +119,6 @@ ], "8": [ - - ], - "9": [ [ { "id": "test", @@ -129,43 +127,57 @@ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "adapterremoval_discarded": [ + "9": [ [ { "id": "test", "single_end": true }, - "test.discarded.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "adapterremoval_paired_interleaved": [ ], - "fastp_html": [ + "discarded_reads": [ [ { "id": "test", "single_end": true }, - "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.discarded.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ], + [ + { + "id": "test", + "single_end": true + }, + "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ], + [ + { + "id": "test", + "single_end": true + }, + "test.fail.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "fastp_log": [ + "fastp_html": [ [ { "id": "test", "single_end": true }, - "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "fastp_reads_fail": [ + "fastp_log": [ [ { "id": "test", "single_end": true }, - "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "merged_reads": [ @@ -186,6 +198,13 @@ }, "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" ], + [ + { + "id": "test", + "single_end": true + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ], [ { "id": "test", @@ -221,9 +240,6 @@ }, "test.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "trimgalore_unpaired": [ - ], "trimgalore_zip": [ @@ -245,14 +261,12 @@ }, "test_trim.log:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "trimmomatic_unpaired_reads": [ - ], "versions": [ "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", "versions.yml:md5,2d5c9b99267e97292e2a581635bd72f7", "versions.yml:md5,aa418419664a944b74696ee0e9ef1c7a", + "versions.yml:md5,ba074f9db361b3f8d0a8cc93c3907a91", "versions.yml:md5,bcfe22d952cc3ae0ac5ff685e16fa4a5", "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" ] @@ -262,18 +276,25 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-09T11:14:22.599187687" + "timestamp": "2025-12-09T13:54:41.801054438" }, "sarscov2 - fastq - paired-end": { "content": [ [ - "test.pair1.truncated.fastq.gz:md5,b2f0ff871e44ccb66bb948524503d4d3", - "test.pair2.truncated.fastq.gz:md5,3a13402b3f1ac1462d10da45c9829444" + "test.pair1.truncated.fastq.gz:md5,b865b4a1d2a7ac9c1caee464e9857da0", + "test.pair2.truncated.fastq.gz:md5,1ec9f8b98d3c6dbf956db0782228b29c" ], - "test.collapsed.fastq.gz:md5,909e9abf6cdfcd32508582dc2768854a", + "test.collapsed.fastq.gz:md5,984b6edf9c613449d2f7ce6dbe0f5550", [ - "test.unpaired.trim_1.fastq.gz:md5,f22935d14248bd936af8d5e3c27e72b2", - "test.unpaired.trim_2.fastq.gz:md5,ce0d8e849e4677a186cd0566b2a6ea15" + "test.discarded.fastq.gz", + "test.fail.fq.gz", + "test.paired.fail.fastq.gz", + "test.unpaired.trim_1.fastq.gz", + "test.unpaired.trim_2.fastq.gz", + "test_1.fail.fastq.gz", + "test_2.fail.fastq.gz", + "test_r1.fail.fq.gz", + "test_r2.fail.fq.gz" ], "test_trim.log:md5,9629761761a34576b3484bf4174f681f", "test.summary:md5,9698e5e5c060bbe64588998fe35f8d71", @@ -282,12 +303,13 @@ "test.fastp.html", 51, [ - "test.paired.fail.fastq.gz", - "test_1.fail.fastq.gz", - "test_2.fail.fastq.gz" + "test.bbduk.log", + "test.cutadapt.log", + "test.fastp.json", + "test.log", + "test.settings", + "test_out.log" ], - "test.discarded.fastq.gz", - "test.bbduk.log", [ { "FASTQ_REMOVEADAPTERS_MERGE:ADAPTERREMOVAL_PE": { @@ -306,6 +328,11 @@ "fastp": "1.0.1" } }, + { + "FASTQ_REMOVEADAPTERS_MERGE:LEEHOM": { + "leehom": "1.2.15" + } + }, { "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { "bbmap": 39.18 @@ -327,19 +354,29 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-09T11:28:02.942964155" + "timestamp": "2025-12-09T13:54:32.103319027" }, "sarscov2 - fastq - single-end": { "content": [ - "test.truncated.fastq.gz:md5,151f9ca2bfb8c52579884fa7c4d6d9f9", + "test.truncated.fastq.gz:md5,6dcea64429b2bcf5e31751f9c8041914", + [ + "test.discarded.fastq.gz", + "test.fail.fastq.gz", + "test.fail.fq.gz" + ], "test_trim.log:md5,e4c3f619e9b0e26847f8f3e3d9af319b", "test.summary:md5,24c973237557a1439c775ca19a5deaa5", 61, "test.fastp.html", 32, - "test.fail.fastq.gz:md5,3e4aaadb66a5b8fc9b881bf39c227abd", - "test.discarded.fastq.gz", - "test.bbduk.log", + [ + "test.bbduk.log", + "test.cutadapt.log", + "test.fastp.json", + "test.log", + "test.settings", + "test_out.log" + ], [ { "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { @@ -358,6 +395,11 @@ "adapterremoval": "2.3.2" } }, + { + "FASTQ_REMOVEADAPTERS_MERGE:LEEHOM": { + "leehom": "1.2.15" + } + }, { "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { "bbmap": 39.18 @@ -379,6 +421,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-09T11:27:46.873445297" + "timestamp": "2025-12-09T13:54:18.384916548" } } \ No newline at end of file From 5854017495b71a3f7bd954caddbc00b4e64c2ce5 Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Tue, 9 Dec 2025 14:26:43 +0000 Subject: [PATCH 36/83] remove ngmerge because cant deal with /1 /2 paired reads --- .../fastq_removeadapters_merge/main.nf | 28 ++++++++----------- .../tests/main.nf.test | 6 +--- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index 14588aa27869..c20cb20ef823 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -1,17 +1,14 @@ -// ok for single end adapter removal -include { TRIMMOMATIC } from '../../../modules/nf-core/trimmomatic/main' // both SE and PE -include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' // both SE and PE -include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' // both SE and PE -include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' // both SE and PE -include { LEEHOM } from '../../../modules/nf-core/leehom/main' // both SE and PE -// // allows merging of paired end reads, but will work for single end reads as well -include { FASTP } from '../../../modules/nf-core/fastp/main' // both SE and PE + merge -include { ADAPTERREMOVAL as ADAPTERREMOVAL_SE } from '../../../modules/nf-core/adapterremoval/main' // both SE and PE + merge +// both SE and PE +include { TRIMMOMATIC } from '../../../modules/nf-core/trimmomatic/main' +include { CUTADAPT } from '../../../modules/nf-core/cutadapt/main' +include { TRIMGALORE } from '../../../modules/nf-core/trimgalore/main' +include { BBMAP_BBDUK } from '../../../modules/nf-core/bbmap/bbduk/main' +include { LEEHOM } from '../../../modules/nf-core/leehom/main' +// both SE and PE, plus merging +include { FASTP } from '../../../modules/nf-core/fastp/main' +include { ADAPTERREMOVAL as ADAPTERREMOVAL_SE } from '../../../modules/nf-core/adapterremoval/main' include { ADAPTERREMOVAL as ADAPTERREMOVAL_PE } from '../../../modules/nf-core/adapterremoval/main' -// // requires paired end because of merging -// include { NGMERGE } from '../../../modules/nf-core/ngmerge/main' - workflow FASTQ_REMOVEADAPTERS_MERGE { take: @@ -28,7 +25,6 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { save_merged // boolean skip_adapterremoval // boolean text_adapters // channel: [ txt ] // adapters to remove, in adapterremoval text format - // skip_ngmerge // boolean main: @@ -81,7 +77,7 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { } if (!skip_leehom) { - LEEHOM(ch_reads) + LEEHOM( ch_reads ) ch_reads = LEEHOM.out.fq_pass .join(LEEHOM.out.unmerged_r1_fq_pass, by: 0, remainder: true) @@ -121,8 +117,8 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { paired: !meta.single_end } - ADAPTERREMOVAL_SE(ch_adapterremoval_in.single, text_adapters) - ADAPTERREMOVAL_PE(ch_adapterremoval_in.paired, text_adapters) + ADAPTERREMOVAL_SE( ch_adapterremoval_in.single, text_adapters ) + ADAPTERREMOVAL_PE( ch_adapterremoval_in.paired, text_adapters ) ch_reads = ADAPTERREMOVAL_SE.out.singles_truncated.mix(ADAPTERREMOVAL_PE.out.paired_truncated) ch_merged_reads = ADAPTERREMOVAL_SE.out.collapsed diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index a5dafcee3aee..435c84781a2b 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -16,7 +16,6 @@ nextflow_workflow { tag "leehom" tag "fastp" tag "adapterremoval" - // tag "ngmerge" test("sarscov2 - fastq - single-end") { config "./nextflow_SE.config" @@ -44,7 +43,6 @@ nextflow_workflow { input[10] = params.save_merged input[11] = false // skip_adapterremoval input[12] = [] // text adapters - // input[13] = true // skip_ngmerge """ } } @@ -94,7 +92,6 @@ nextflow_workflow { input[10] = params.save_merged input[11] = false // skip_adapterremoval input[12] = [] // text adapters - // input[13] = true // skip_ngmerge """ } } @@ -143,7 +140,7 @@ nextflow_workflow { // input[10] = params.save_merged // input[11] = false // skip_adapterremoval // input[12] = [] // text adapters - // // input[13] = true // skip_ngmerge + // input[13] = false // skip_ngmerge // // """ // // } // // } @@ -185,7 +182,6 @@ nextflow_workflow { input[10] = params.save_merged input[11] = false // skip_adapterremoval input[12] = [] // text adapters - // input[13] = true // skip_ngmerge """ } } From 3001aa772f14034f46769b0d89cdc566853832ba Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Tue, 9 Dec 2025 14:29:01 +0000 Subject: [PATCH 37/83] paired end no merge test --- .../tests/main.nf.test | 88 +++++++++++-------- .../tests/main.nf.test.snap | 77 ++++++++++++++++ 2 files changed, 126 insertions(+), 39 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index 435c84781a2b..d937cfeb85db 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -114,45 +114,55 @@ nextflow_workflow { } } - // // test("sarscov2 - fastq - paired-end, no merging") { - // // when { params { - // // samtools_arg = '' - // // } - // // workflow { - // // """ - // // input[0] = [ - // // [ id:'test_paired', single_end:false ], - // // [ - // // file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), - // // file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) - // // ] - // // ] - - // // input[1] = false // skip_trimmomatic - // // input[2] = false // skip_cutadapt - // // input[3] = false // skip_trimgalore - // // input[4] = false // skip_bbduk - // // input[5] = [] // contaminants - // input[6] = false // skip_leehom - // input[7] = false // skip_fastp - // input[8] = false // fastp_discard_trimmed_pass - // input[9] = true // fastp_save_trimmed_fail - // input[10] = params.save_merged - // input[11] = false // skip_adapterremoval - // input[12] = [] // text adapters - // input[13] = false // skip_ngmerge - // // """ - // // } - // // } - - // // then { - // // assertAll( - // // { assert workflow.success }, - // // workflow.out.adapterremoval_collapsed[0][1], - // // { assert snapshot(workflow.out).match() } - // // ) - // // } - // // } + test("sarscov2 - fastq - paired-end - no-merge") { + config "./nextflow_PE.config" + when { + params { + save_merged = false + adapterremoval_args = save_merged ? "--collapse" : "" + } + workflow { + """ + input[0] = [ + [ id:'test', single_end:false ], + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ] + + input[1] = false // skip_trimmomatic + input[2] = false // skip_cutadapt + input[3] = false // skip_trimgalore + input[4] = false // skip_bbduk + input[5] = [] // contaminants + input[6] = false // skip_leehom + input[7] = false // skip_fastp + input[8] = false // fastp_discard_trimmed_pass + input[9] = true // fastp_save_trimmed_fail + input[10] = params.save_merged + input[11] = false // skip_adapterremoval + input[12] = [] // text adapters + """ + } + } + + then { + assert workflow.success + assert snapshot( + workflow.out.reads[0][1], + workflow.out.discarded_reads.collect { file(it[1]).name }, + workflow.out.trimmomatic_trim_log[0][1], + workflow.out.trimmomatic_summary[0][1], + path(workflow.out.trimgalore_log[0][1][0]).readLines().size(), + path(workflow.out.trimgalore_log[0][1][1]).readLines().size(), + file(workflow.out.fastp_html[0][1]).name, + path(workflow.out.fastp_log[0][1]).readLines().size(), + workflow.out.multiqc_files.collect { file(it[1]).name }, + workflow.out.versions.collect { path(it).yaml } + ).match() + } + } test("sarscov2 - fastq - single-end - stub") { diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap index 690cf8aa97c3..675de50d3378 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap @@ -422,5 +422,82 @@ "nextflow": "25.10.2" }, "timestamp": "2025-12-09T13:54:18.384916548" + }, + "sarscov2 - fastq - paired-end - no-merge": { + "content": [ + [ + "test.pair1.truncated.fastq.gz:md5,b042d3460f77b69f0a4d2a5cb20b1b25", + "test.pair2.truncated.fastq.gz:md5,510c140a51b7b0457e92e658113acbdc" + ], + [ + "test.discarded.fastq.gz", + "test.fail.fq.gz", + "test.paired.fail.fastq.gz", + "test.unpaired.trim_1.fastq.gz", + "test.unpaired.trim_2.fastq.gz", + "test_1.fail.fastq.gz", + "test_2.fail.fastq.gz", + "test_r1.fail.fq.gz", + "test_r2.fail.fq.gz" + ], + "test_trim.log:md5,9629761761a34576b3484bf4174f681f", + "test.summary:md5,9698e5e5c060bbe64588998fe35f8d71", + 60, + 63, + "test.fastp.html", + 51, + [ + "test.bbduk.log", + "test.cutadapt.log", + "test.fastp.json", + "test.log", + "test.settings", + "test_out.log" + ], + [ + { + "FASTQ_REMOVEADAPTERS_MERGE:ADAPTERREMOVAL_PE": { + "adapterremoval": "2.3.2" + } + }, + { + "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { + "trimgalore": "0.6.10", + "cutadapt": 4.9, + "pigz": 2.8 + } + }, + { + "FASTQ_REMOVEADAPTERS_MERGE:FASTP": { + "fastp": "1.0.1" + } + }, + { + "FASTQ_REMOVEADAPTERS_MERGE:LEEHOM": { + "leehom": "1.2.15" + } + }, + { + "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { + "bbmap": 39.18 + } + }, + { + "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { + "trimmomatic": 0.39 + } + }, + { + "FASTQ_REMOVEADAPTERS_MERGE:CUTADAPT": { + "cutadapt": 5.0 + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-09T14:28:19.369829207" } } \ No newline at end of file From 8637cb132ae6696fc49ff74c2dd1787c38741b67 Mon Sep 17 00:00:00 2001 From: Joon Klaps Date: Tue, 9 Dec 2025 15:48:24 +0100 Subject: [PATCH 38/83] New module: clusty (#9533) * new module clusty * patch links docs * fix prettier * remove non-mandatory input 'algorithm' * also patch stub input --- modules/nf-core/clusty/environment.yml | 7 + modules/nf-core/clusty/main.nf | 50 +++++++ modules/nf-core/clusty/meta.yml | 83 ++++++++++++ modules/nf-core/clusty/tests/main.nf.test | 92 +++++++++++++ .../nf-core/clusty/tests/main.nf.test.snap | 125 ++++++++++++++++++ modules/nf-core/clusty/tests/nextflow.config | 5 + 6 files changed, 362 insertions(+) create mode 100644 modules/nf-core/clusty/environment.yml create mode 100644 modules/nf-core/clusty/main.nf create mode 100644 modules/nf-core/clusty/meta.yml create mode 100644 modules/nf-core/clusty/tests/main.nf.test create mode 100644 modules/nf-core/clusty/tests/main.nf.test.snap create mode 100644 modules/nf-core/clusty/tests/nextflow.config diff --git a/modules/nf-core/clusty/environment.yml b/modules/nf-core/clusty/environment.yml new file mode 100644 index 000000000000..afbbde862837 --- /dev/null +++ b/modules/nf-core/clusty/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::clusty=1.2.2" diff --git a/modules/nf-core/clusty/main.nf b/modules/nf-core/clusty/main.nf new file mode 100644 index 000000000000..8d819443e628 --- /dev/null +++ b/modules/nf-core/clusty/main.nf @@ -0,0 +1,50 @@ + +process CLUSTY { + tag "$meta.id" + label 'process_medium' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/clusty:1.2.2--h9ee0642_0': + 'biocontainers/clusty:1.2.2--h9ee0642_0' }" + + input: + tuple val(meta), path(distances) + tuple val(meta2), path(objects) + + output: + tuple val(meta), path("*.tsv"), emit: assignments + tuple val("${task.process}"), val('clusty'), eval('echo $(clusty --version 2>&1)'), topic: versions, emit: versions_clusty + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def objects_arg = objects ? "--objects-file $objects" : "" + + if ("${distances}" == "${prefix}.tsv") error "Input and output names are the same, set prefix in module configuration to disambiguate!" + + """ + clusty \\ + $args \\ + -t $task.cpus \\ + ${objects_arg} \\ + ${distances} \\ + ${prefix}.tsv + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def objects_arg = objects ? "--objects-file $objects" : "" + + if ("${distances}" == "${prefix}.tsv") error "Input and output names are the same, set prefix in module configuration to disambiguate!" + + """ + echo $args + echo ${objects_arg} + touch ${prefix}.tsv + """ +} diff --git a/modules/nf-core/clusty/meta.yml b/modules/nf-core/clusty/meta.yml new file mode 100644 index 000000000000..dadd04d488ad --- /dev/null +++ b/modules/nf-core/clusty/meta.yml @@ -0,0 +1,83 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "clusty" +description: Clusty is a tool for large-scale clustering using sparse distance + matrices, suitable for datasets with millions of objects. +keywords: + - cluster + - network + - contig + - scaffold + - alignment + - protein +tools: + - "clusty": + description: "Clusty is a tool for large-scale data clustering." + homepage: "https://github.com/refresh-bio/clusty" + documentation: "https://github.com/refresh-bio/clusty" + tool_dev_url: "https://github.com/refresh-bio/clusty" + doi: "10.1038/s41592-025-02701-7" + licence: ["GPL v3-or-later"] + identifier: "" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - distances: + type: file + description: pairwise distances file (e.g., TSV format) + pattern: "*.tsv" + ontologies: + - edam: "http://edamontology.org/format_3475" # TSV + - - meta2: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - objects: + type: file + description: Optional TSV file containing object identifiers + pattern: "*.tsv" + ontologies: + - edam: "http://edamontology.org/format_3475" # TSV + +output: + assignments: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.tsv": + type: file + description: TSV file with cluster assignments + pattern: "*.tsv" + ontologies: + - edam: "http://edamontology.org/format_3475" # TSV + versions_clusty: + - - ${task.process}: + type: string + description: The name of the process + - clusty: + type: string + description: The name of the tool + - "echo $(clusty --version 2>&1": + type: string + description: The version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - clusty: + type: string + description: The name of the tool + - "echo $(clusty --version 2>&1": + type: string + description: The version of the tool +authors: + - "@Joon-Klaps" +maintainers: + - "@Joon-Klaps" diff --git a/modules/nf-core/clusty/tests/main.nf.test b/modules/nf-core/clusty/tests/main.nf.test new file mode 100644 index 000000000000..5301da3226e4 --- /dev/null +++ b/modules/nf-core/clusty/tests/main.nf.test @@ -0,0 +1,92 @@ +nextflow_process { + name "Test Process CLUSTY" + script "../main.nf" + process "CLUSTY" + + tag "modules" + tag "modules_nfcore" + tag "clusty" + + test("generic - only distances") { + + when { + params { + clusty_args = '--id-cols id1 id2 --distance-col ani --similarity --min ani 0.70' + } + + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'generic/tsv/ani.tsv', checkIfExists: true), + ] + input[1] = [[:], []] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + } + + test("generic - distances - objects") { + + when { + params { + clusty_args = '--id-cols name1 name2 --distance-col ani --similarity --min ani 0.70' + } + + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'generic/tsv/ani.tsv', checkIfExists: true), + ] + input[1] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'generic/txt/ani_ids.txt', checkIfExists: true), + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + } + + test("generic - only distances - stub") { + + options "-stub" + + when { + params { + clusty_args = '--id-cols name1 name2 --distance-col ani --similarity --min ani 0.70' + } + + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'generic/tsv/ani.tsv', checkIfExists: true), + ] + input[1] = [[:], []] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/clusty/tests/main.nf.test.snap b/modules/nf-core/clusty/tests/main.nf.test.snap new file mode 100644 index 000000000000..2a389ddcabff --- /dev/null +++ b/modules/nf-core/clusty/tests/main.nf.test.snap @@ -0,0 +1,125 @@ +{ + "generic - distances - objects": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.tsv:md5,cea71211069e4aeed9e021ebebc038e7" + ] + ], + "1": [ + [ + "CLUSTY", + "clusty", + "1.2.2" + ] + ], + "assignments": [ + [ + { + "id": "test" + }, + "test.tsv:md5,cea71211069e4aeed9e021ebebc038e7" + ] + ], + "versions_clusty": [ + [ + "CLUSTY", + "clusty", + "1.2.2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-09T12:35:44.503401" + }, + "generic - only distances - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "CLUSTY", + "clusty", + "1.2.2" + ] + ], + "assignments": [ + [ + { + "id": "test" + }, + "test.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_clusty": [ + [ + "CLUSTY", + "clusty", + "1.2.2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-09T12:36:00.849772" + }, + "generic - only distances": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.tsv:md5,9c4d0da996fe7c4579b473f4148623ec" + ] + ], + "1": [ + [ + "CLUSTY", + "clusty", + "1.2.2" + ] + ], + "assignments": [ + [ + { + "id": "test" + }, + "test.tsv:md5,9c4d0da996fe7c4579b473f4148623ec" + ] + ], + "versions_clusty": [ + [ + "CLUSTY", + "clusty", + "1.2.2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-09T12:35:28.037382" + } +} \ No newline at end of file diff --git a/modules/nf-core/clusty/tests/nextflow.config b/modules/nf-core/clusty/tests/nextflow.config new file mode 100644 index 000000000000..2fa76f4f9668 --- /dev/null +++ b/modules/nf-core/clusty/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: CLUSTY { + ext.args = params.clusty_args + } +} From a7bc445b68c34fdcd81e69829ab6c9855cb89b36 Mon Sep 17 00:00:00 2001 From: Felix Lenner <52530259+fellen31@users.noreply.github.com> Date: Tue, 9 Dec 2025 16:34:09 +0100 Subject: [PATCH 39/83] Bump TRGT to 4.1.0 (#9514) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bump TRGT to 4.1.0 * Switch to topics * Update modules/nf-core/trgt/genotype/tests/main.nf.test Co-authored-by: Matthias Hörtenhuber * remove duplicate versions --------- Co-authored-by: Matthias Hörtenhuber --- modules/nf-core/trgt/genotype/environment.yml | 2 +- modules/nf-core/trgt/genotype/main.nf | 8 +- modules/nf-core/trgt/genotype/meta.yml | 28 ++++-- .../nf-core/trgt/genotype/tests/main.nf.test | 4 +- .../trgt/genotype/tests/main.nf.test.snap | 88 +++++++++++++------ modules/nf-core/trgt/merge/environment.yml | 2 +- modules/nf-core/trgt/merge/main.nf | 6 +- modules/nf-core/trgt/merge/meta.yml | 28 ++++-- modules/nf-core/trgt/merge/tests/main.nf.test | 11 ++- .../trgt/merge/tests/main.nf.test.snap | 67 ++++++++++---- modules/nf-core/trgt/plot/environment.yml | 2 +- modules/nf-core/trgt/plot/main.nf | 6 +- modules/nf-core/trgt/plot/meta.yml | 28 ++++-- modules/nf-core/trgt/plot/tests/main.nf.test | 4 +- .../nf-core/trgt/plot/tests/main.nf.test.snap | 28 ++++-- 15 files changed, 219 insertions(+), 93 deletions(-) diff --git a/modules/nf-core/trgt/genotype/environment.yml b/modules/nf-core/trgt/genotype/environment.yml index 8174b1f6505c..5ff336d40646 100644 --- a/modules/nf-core/trgt/genotype/environment.yml +++ b/modules/nf-core/trgt/genotype/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::trgt=4.0.0 + - bioconda::trgt=4.1.0 diff --git a/modules/nf-core/trgt/genotype/main.nf b/modules/nf-core/trgt/genotype/main.nf index c58f67af1cee..1fe75f7d60de 100644 --- a/modules/nf-core/trgt/genotype/main.nf +++ b/modules/nf-core/trgt/genotype/main.nf @@ -4,8 +4,8 @@ process TRGT_GENOTYPE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/trgt:4.0.0--h9ee0642_0': - 'biocontainers/trgt:4.0.0--h9ee0642_0' }" + 'https://depot.galaxyproject.org/singularity/trgt:4.1.0--h9ee0642_0': + 'biocontainers/trgt:4.1.0--h9ee0642_0' }" input: tuple val(meta) , path(bam), path(bai), val(karyotype) @@ -15,8 +15,8 @@ process TRGT_GENOTYPE { output: tuple val(meta), path("*.vcf.gz") , emit: vcf - tuple val(meta), path("*.spanning.bam"), emit: bam , optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*.spanning.bam"), emit: bam, optional: true + tuple val("${task.process}"), val('trgt'), eval("trgt --version | sed 's/.* //g'"), emit: versions_trgt, topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/trgt/genotype/meta.yml b/modules/nf-core/trgt/genotype/meta.yml index 29b5e046fa3c..fef18e236b9d 100644 --- a/modules/nf-core/trgt/genotype/meta.yml +++ b/modules/nf-core/trgt/genotype/meta.yml @@ -94,14 +94,28 @@ output: description: BAM file with pieces of reads aligning to repeats pattern: "*.spanning.bam" ontologies: [] - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + versions_trgt: + - - ${task.process}: + type: string + description: The name of the process + - trgt: + type: string + description: The name of the tool + - trgt --version | sed 's/.* //g': + type: eval + description: The expression to obtain the version of the tool - ontologies: - - edam: http://edamontology.org/format_3750 # YAML +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - trgt: + type: string + description: The name of the tool + - trgt --version | sed 's/.* //g': + type: eval + description: The expression to obtain the version authors: - "@Schmytzi" - "@fellen31" diff --git a/modules/nf-core/trgt/genotype/tests/main.nf.test b/modules/nf-core/trgt/genotype/tests/main.nf.test index 12fd8335c3b6..6f2c663d23d4 100644 --- a/modules/nf-core/trgt/genotype/tests/main.nf.test +++ b/modules/nf-core/trgt/genotype/tests/main.nf.test @@ -59,7 +59,9 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out, + ).match() } ) } diff --git a/modules/nf-core/trgt/genotype/tests/main.nf.test.snap b/modules/nf-core/trgt/genotype/tests/main.nf.test.snap index b5a6591e3cd1..70dd85f39bbd 100644 --- a/modules/nf-core/trgt/genotype/tests/main.nf.test.snap +++ b/modules/nf-core/trgt/genotype/tests/main.nf.test.snap @@ -7,7 +7,7 @@ { "id": "test" }, - "test.vcf.gz:md5,9d5f7877193d0c8a6fbce7c9f82ab05b" + "test.vcf.gz:md5,cb694061956ddcd63772baf9a0720624" ] ], "1": [ @@ -15,18 +15,22 @@ { "id": "test" }, - "test.spanning.bam:md5,22cb334e5936fa940c3a78c89ba7477c" + "test.spanning.bam:md5,47da98a17e3bc7b4b234c59a435a38ca" ] ], "2": [ - "versions.yml:md5,cf70c46a111ed5f7a9bdd432b6f579b6" + [ + "TRGT_GENOTYPE", + "trgt", + "4.1.0-39fa24c" + ] ], "bam": [ [ { "id": "test" }, - "test.spanning.bam:md5,22cb334e5936fa940c3a78c89ba7477c" + "test.spanning.bam:md5,47da98a17e3bc7b4b234c59a435a38ca" ] ], "vcf": [ @@ -34,11 +38,15 @@ { "id": "test" }, - "test.vcf.gz:md5,9d5f7877193d0c8a6fbce7c9f82ab05b" + "test.vcf.gz:md5,cb694061956ddcd63772baf9a0720624" ] ], - "versions": [ - "versions.yml:md5,cf70c46a111ed5f7a9bdd432b6f579b6" + "versions_trgt": [ + [ + "TRGT_GENOTYPE", + "trgt", + "4.1.0-39fa24c" + ] ] } ], @@ -46,7 +54,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-23T11:19:06.149363798" + "timestamp": "2025-12-09T16:16:00.489435938" }, "homo sapiens - [bam,bai,[]], [fa,fai], bed - stub": { "content": [ @@ -56,7 +64,7 @@ { "id": "test" }, - "test.vcf.gz:md5,03899fb4a8ca115e54a1db46800096cb" + "test.vcf.gz:md5,2015f1ef3d10bf8ce99882099b61b185" ] ], "1": [ @@ -64,18 +72,22 @@ { "id": "test" }, - "test.spanning.bam:md5,0f1755fd47e7c942fda2282c5da2e8e8" + "test.spanning.bam:md5,1370db3a5d025cdde50676fab4235c5f" ] ], "2": [ - "versions.yml:md5,cf70c46a111ed5f7a9bdd432b6f579b6" + [ + "TRGT_GENOTYPE", + "trgt", + "4.1.0-39fa24c" + ] ], "bam": [ [ { "id": "test" }, - "test.spanning.bam:md5,0f1755fd47e7c942fda2282c5da2e8e8" + "test.spanning.bam:md5,1370db3a5d025cdde50676fab4235c5f" ] ], "vcf": [ @@ -83,11 +95,15 @@ { "id": "test" }, - "test.vcf.gz:md5,03899fb4a8ca115e54a1db46800096cb" + "test.vcf.gz:md5,2015f1ef3d10bf8ce99882099b61b185" ] ], - "versions": [ - "versions.yml:md5,cf70c46a111ed5f7a9bdd432b6f579b6" + "versions_trgt": [ + [ + "TRGT_GENOTYPE", + "trgt", + "4.1.0-39fa24c" + ] ] } ], @@ -95,7 +111,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-23T11:19:21.404862883" + "timestamp": "2025-12-09T16:16:15.759484541" }, "homo sapiens - [bam,bai,XX], [fa,fai], bed - stub": { "content": [ @@ -117,7 +133,11 @@ ] ], "2": [ - "versions.yml:md5,cf70c46a111ed5f7a9bdd432b6f579b6" + [ + "TRGT_GENOTYPE", + "trgt", + "4.1.0-39fa24c" + ] ], "bam": [ [ @@ -135,8 +155,12 @@ "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,cf70c46a111ed5f7a9bdd432b6f579b6" + "versions_trgt": [ + [ + "TRGT_GENOTYPE", + "trgt", + "4.1.0-39fa24c" + ] ] } ], @@ -144,7 +168,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-23T11:19:16.057879354" + "timestamp": "2025-12-09T16:16:10.709433028" }, "homo sapiens - [bam,bai,[]], [fa,fai], bed": { "content": [ @@ -154,7 +178,7 @@ { "id": "test" }, - "test.vcf.gz:md5,03899fb4a8ca115e54a1db46800096cb" + "test.vcf.gz:md5,2015f1ef3d10bf8ce99882099b61b185" ] ], "1": [ @@ -162,18 +186,22 @@ { "id": "test" }, - "test.spanning.bam:md5,0f1755fd47e7c942fda2282c5da2e8e8" + "test.spanning.bam:md5,1370db3a5d025cdde50676fab4235c5f" ] ], "2": [ - "versions.yml:md5,cf70c46a111ed5f7a9bdd432b6f579b6" + [ + "TRGT_GENOTYPE", + "trgt", + "4.1.0-39fa24c" + ] ], "bam": [ [ { "id": "test" }, - "test.spanning.bam:md5,0f1755fd47e7c942fda2282c5da2e8e8" + "test.spanning.bam:md5,1370db3a5d025cdde50676fab4235c5f" ] ], "vcf": [ @@ -181,11 +209,15 @@ { "id": "test" }, - "test.vcf.gz:md5,03899fb4a8ca115e54a1db46800096cb" + "test.vcf.gz:md5,2015f1ef3d10bf8ce99882099b61b185" ] ], - "versions": [ - "versions.yml:md5,cf70c46a111ed5f7a9bdd432b6f579b6" + "versions_trgt": [ + [ + "TRGT_GENOTYPE", + "trgt", + "4.1.0-39fa24c" + ] ] } ], @@ -193,6 +225,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-23T11:19:10.595588655" + "timestamp": "2025-12-09T16:16:05.648952742" } } \ No newline at end of file diff --git a/modules/nf-core/trgt/merge/environment.yml b/modules/nf-core/trgt/merge/environment.yml index 8174b1f6505c..5ff336d40646 100644 --- a/modules/nf-core/trgt/merge/environment.yml +++ b/modules/nf-core/trgt/merge/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::trgt=4.0.0 + - bioconda::trgt=4.1.0 diff --git a/modules/nf-core/trgt/merge/main.nf b/modules/nf-core/trgt/merge/main.nf index 815d291c0365..07cf2d9c640f 100644 --- a/modules/nf-core/trgt/merge/main.nf +++ b/modules/nf-core/trgt/merge/main.nf @@ -4,8 +4,8 @@ process TRGT_MERGE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/trgt:4.0.0--h9ee0642_0': - 'biocontainers/trgt:4.0.0--h9ee0642_0' }" + 'https://depot.galaxyproject.org/singularity/trgt:4.1.0--h9ee0642_0': + 'biocontainers/trgt:4.1.0--h9ee0642_0' }" input: tuple val(meta) , path(vcfs), path(tbis) @@ -14,7 +14,7 @@ process TRGT_MERGE { output: tuple val(meta), path("*.{vcf,vcf.gz,bcf,bcf.gz}"), emit: vcf - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('trgt'), eval("trgt --version | sed 's/.* //g'"), emit: versions_trgt, topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/trgt/merge/meta.yml b/modules/nf-core/trgt/merge/meta.yml index 3020ea10976e..72ed57d50a93 100644 --- a/modules/nf-core/trgt/merge/meta.yml +++ b/modules/nf-core/trgt/merge/meta.yml @@ -72,14 +72,28 @@ output: description: "Merged output file" pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" ontologies: [] - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + versions_trgt: + - - ${task.process}: + type: string + description: The name of the process + - trgt: + type: string + description: The name of the tool + - trgt --version | sed 's/.* //g': + type: eval + description: The expression to obtain the version of the tool - ontologies: - - edam: http://edamontology.org/format_3750 # YAML +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - trgt: + type: string + description: The name of the tool + - trgt --version | sed 's/.* //g': + type: eval + description: The expression to obtain the version authors: - "@Schmytzi" maintainers: diff --git a/modules/nf-core/trgt/merge/tests/main.nf.test b/modules/nf-core/trgt/merge/tests/main.nf.test index d25e871ed28a..5b3697a1e233 100644 --- a/modules/nf-core/trgt/merge/tests/main.nf.test +++ b/modules/nf-core/trgt/merge/tests/main.nf.test @@ -95,7 +95,7 @@ nextflow_process { path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.sampleCount, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } @@ -120,7 +120,7 @@ nextflow_process { path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.sampleCount, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } @@ -165,7 +165,7 @@ nextflow_process { path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.sampleCount, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } @@ -187,7 +187,10 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out, + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } ) } } diff --git a/modules/nf-core/trgt/merge/tests/main.nf.test.snap b/modules/nf-core/trgt/merge/tests/main.nf.test.snap index b299852bb314..147860e39619 100644 --- a/modules/nf-core/trgt/merge/tests/main.nf.test.snap +++ b/modules/nf-core/trgt/merge/tests/main.nf.test.snap @@ -4,30 +4,42 @@ "ec69cbc40d4a9766d87a62ba4835ae52", "VcfFile [chromosomes=[chr22], sampleCount=2, variantCount=1, phased=false, phasedAutodetect=false]", 2, - [ - "versions.yml:md5,32d0e033481d117ce09ad340b854ac07" - ] + { + "versions_trgt": [ + [ + "TRGT_MERGE", + "trgt", + "4.1.0-39fa24c" + ] + ] + } ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-23T11:19:32.225480759" + "timestamp": "2025-12-06T13:08:24.392230593" }, "homo sapiens - 2 VCFs": { "content": [ "ec69cbc40d4a9766d87a62ba4835ae52", "VcfFile [chromosomes=[chr22], sampleCount=2, variantCount=1, phased=false, phasedAutodetect=false]", 2, - [ - "versions.yml:md5,32d0e033481d117ce09ad340b854ac07" - ] + { + "versions_trgt": [ + [ + "TRGT_MERGE", + "trgt", + "4.1.0-39fa24c" + ] + ] + } ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-23T11:19:26.833626863" + "timestamp": "2025-12-06T13:08:18.192678929" }, "homo sapiens - 2 VCFs - stub": { "content": [ @@ -41,7 +53,11 @@ ] ], "1": [ - "versions.yml:md5,32d0e033481d117ce09ad340b854ac07" + [ + "TRGT_MERGE", + "trgt", + "4.1.0-39fa24c" + ] ], "vcf": [ [ @@ -51,8 +67,21 @@ "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,32d0e033481d117ce09ad340b854ac07" + "versions_trgt": [ + [ + "TRGT_MERGE", + "trgt", + "4.1.0-39fa24c" + ] + ] + }, + { + "versions_trgt": [ + [ + "TRGT_MERGE", + "trgt", + "4.1.0-39fa24c" + ] ] } ], @@ -60,21 +89,27 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-23T11:19:48.710491165" + "timestamp": "2025-12-06T13:08:42.242325427" }, "homo sapiens - 1 VCF - --force-single": { "content": [ "57131f453c695cbea40812f6c246d0f", "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=1, phased=false, phasedAutodetect=false]", 1, - [ - "versions.yml:md5,32d0e033481d117ce09ad340b854ac07" - ] + { + "versions_trgt": [ + [ + "TRGT_MERGE", + "trgt", + "4.1.0-39fa24c" + ] + ] + } ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-23T11:19:42.468465675" + "timestamp": "2025-12-06T13:08:36.269439614" } } \ No newline at end of file diff --git a/modules/nf-core/trgt/plot/environment.yml b/modules/nf-core/trgt/plot/environment.yml index 8174b1f6505c..5ff336d40646 100644 --- a/modules/nf-core/trgt/plot/environment.yml +++ b/modules/nf-core/trgt/plot/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::trgt=4.0.0 + - bioconda::trgt=4.1.0 diff --git a/modules/nf-core/trgt/plot/main.nf b/modules/nf-core/trgt/plot/main.nf index e252fd25efe9..c0d70507e2e9 100644 --- a/modules/nf-core/trgt/plot/main.nf +++ b/modules/nf-core/trgt/plot/main.nf @@ -4,8 +4,8 @@ process TRGT_PLOT { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/trgt:4.0.0--h9ee0642_0': - 'biocontainers/trgt:4.0.0--h9ee0642_0' }" + 'https://depot.galaxyproject.org/singularity/trgt:4.1.0--h9ee0642_0': + 'biocontainers/trgt:4.1.0--h9ee0642_0' }" input: tuple val(meta) , path(bam), path(bai), path(vcf), path(tbi), val(repeat_id) @@ -15,7 +15,7 @@ process TRGT_PLOT { output: tuple val(meta), path("*.{png,pdf,svg}"), emit: plot - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('trgt'), eval("trgt --version | sed 's/.* //g'"), emit: versions_trgt, topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/trgt/plot/meta.yml b/modules/nf-core/trgt/plot/meta.yml index 00a06ac000a5..8435c7aecd5d 100644 --- a/modules/nf-core/trgt/plot/meta.yml +++ b/modules/nf-core/trgt/plot/meta.yml @@ -91,14 +91,28 @@ output: description: "Plot of region and reads spanning tandem repeat" pattern: "*.{png,pdf,svg}" ontologies: [] - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + versions_trgt: + - - ${task.process}: + type: string + description: The name of the process + - trgt: + type: string + description: The name of the tool + - trgt --version | sed 's/.* //g': + type: eval + description: The expression to obtain the version of the tool - ontologies: - - edam: http://edamontology.org/format_3750 # YAML +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - trgt: + type: string + description: The name of the tool + - trgt --version | sed 's/.* //g': + type: eval + description: The expression to obtain the version authors: - "@Schmytzi" maintainers: diff --git a/modules/nf-core/trgt/plot/tests/main.nf.test b/modules/nf-core/trgt/plot/tests/main.nf.test index 175da2e4c946..a7fd516b3a3e 100644 --- a/modules/nf-core/trgt/plot/tests/main.nf.test +++ b/modules/nf-core/trgt/plot/tests/main.nf.test @@ -107,7 +107,7 @@ nextflow_process { { assert process.success }, { assert snapshot( file(process.out.plot.get(0).get(1)).name, //unstable - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } @@ -136,7 +136,7 @@ nextflow_process { { assert process.success }, { assert snapshot( file(process.out.plot.get(0).get(1)).name, //unstable - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } diff --git a/modules/nf-core/trgt/plot/tests/main.nf.test.snap b/modules/nf-core/trgt/plot/tests/main.nf.test.snap index 18d41e94c0ee..4590da7275fb 100644 --- a/modules/nf-core/trgt/plot/tests/main.nf.test.snap +++ b/modules/nf-core/trgt/plot/tests/main.nf.test.snap @@ -2,27 +2,39 @@ "homo sapiens - [bam, bai, vcf, TEST], fasta, fai, bed - stub": { "content": [ "test.png", - [ - "versions.yml:md5,011b1667b12181926498f87d148ee365" - ] + { + "versions_trgt": [ + [ + "TRGT_PLOT", + "trgt", + "4.1.0-39fa24c" + ] + ] + } ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-23T11:20:01.293786322" + "timestamp": "2025-12-06T13:08:55.463192387" }, "homo sapiens - [bam, bai, vcf, TEST], fasta, fai, bed": { "content": [ "test_TEST.png", - [ - "versions.yml:md5,011b1667b12181926498f87d148ee365" - ] + { + "versions_trgt": [ + [ + "TRGT_PLOT", + "trgt", + "4.1.0-39fa24c" + ] + ] + } ], "meta": { "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-23T11:19:54.583487786" + "timestamp": "2025-12-06T13:08:48.783944144" } } \ No newline at end of file From 68d64858cf9eed58775f0764fbe5e81e915cb7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Tue, 9 Dec 2025 16:38:04 +0100 Subject: [PATCH 40/83] fix missing quotes (#9535) --- .../nf-core/bamstats/generalstats/meta.yml | 10 ++++--- modules/nf-core/bedgovcf/meta.yml | 10 ++++--- modules/nf-core/fastqc/meta.yml | 14 +++++---- modules/nf-core/haplogrep3/classify/meta.yml | 14 +++++---- modules/nf-core/multiqc/meta.yml | 14 +++++---- modules/nf-core/qsv/cat/meta.yml | 19 +++++++++--- modules/nf-core/ribodetector/meta.yml | 30 ++++++++++--------- modules/nf-core/samtools/sort/meta.yml | 1 + modules/nf-core/samtools/stats/meta.yml | 17 ++++++----- modules/nf-core/samtools/view/meta.yml | 14 +++++---- .../nf-core/semibin/singleeasybin/meta.yml | 13 ++++++-- modules/nf-core/strdrop/build/meta.yml | 1 + modules/nf-core/tabix/tabix/meta.yml | 22 +++++++------- 13 files changed, 109 insertions(+), 70 deletions(-) diff --git a/modules/nf-core/bamstats/generalstats/meta.yml b/modules/nf-core/bamstats/generalstats/meta.yml index e66ce89b89e0..5c7b966ae63c 100644 --- a/modules/nf-core/bamstats/generalstats/meta.yml +++ b/modules/nf-core/bamstats/generalstats/meta.yml @@ -45,9 +45,10 @@ output: - bamstats: type: string description: The name of the tool - - 'bamstats --version | grep "version: " | sed -e s"/version: //': - type: string - description: The version of the tool + - 'bamstats --version | grep "version: " | sed -e s"/version: //"': + type: eval + description: The expression to obtain the version of the tool + topics: versions: - - ${task.process}: @@ -56,8 +57,9 @@ topics: - bamstats: type: string description: The name of the tool - - 'bamstats --version | grep "version: " | sed -e s"/version: //': + - 'bamstats --version | grep "version: " | sed -e s"/version: //"': type: eval description: The expression to obtain the version of the tool + authors: - "@johnoooh" diff --git a/modules/nf-core/bedgovcf/meta.yml b/modules/nf-core/bedgovcf/meta.yml index 973ce1b12143..38f0300a7544 100644 --- a/modules/nf-core/bedgovcf/meta.yml +++ b/modules/nf-core/bedgovcf/meta.yml @@ -71,9 +71,10 @@ output: - bgzip: type: string description: The tool name - - bgzip --version | head -1 | sed "s/bgzip (htslib: + - bgzip --version | head -1 | sed "s/bgzip (htslib) //": type: eval - description: The tool version + description: The expression to obtain the version of the tool + topics: versions: - - ${task.process}: @@ -91,8 +92,9 @@ topics: - bgzip: type: string description: The tool name - - bgzip --version | head -1 | sed "s/bgzip (htslib: + - bgzip --version | head -1 | sed "s/bgzip (htslib) //": type: eval - description: The tool version + description: The expression to obtain the version of the tool + authors: - "@nvnieuwk" diff --git a/modules/nf-core/fastqc/meta.yml b/modules/nf-core/fastqc/meta.yml index f988697a2941..3e812b30f870 100644 --- a/modules/nf-core/fastqc/meta.yml +++ b/modules/nf-core/fastqc/meta.yml @@ -60,9 +60,10 @@ output: - fastqc: type: string description: The tool name - - fastqc --version | sed "/FastQC v/!d; s/.*v//: - type: string - description: The command used to generate the version of the tool + - fastqc --version | sed "/FastQC v/!d; s/.*v//": + type: eval + description: The expression to obtain the version of the tool + topics: versions: - - ${task.process}: @@ -71,9 +72,10 @@ topics: - fastqc: type: string description: The tool name - - fastqc --version | sed "/FastQC v/!d; s/.*v//: - type: string - description: The command used to generate the version of the tool + - fastqc --version | sed "/FastQC v/!d; s/.*v//": + type: eval + description: The expression to obtain the version of the tool + authors: - "@drpatelh" - "@grst" diff --git a/modules/nf-core/haplogrep3/classify/meta.yml b/modules/nf-core/haplogrep3/classify/meta.yml index 53e40aa6441e..54b7efdf7bda 100644 --- a/modules/nf-core/haplogrep3/classify/meta.yml +++ b/modules/nf-core/haplogrep3/classify/meta.yml @@ -42,9 +42,10 @@ output: - haplogrep3: type: string description: The tool name - - haplogrep3 | sed -n 's/.*Haplogrep 3 \\([0-9.]\\+\\': - type: string - description: The command used to generate the version of the tool + - haplogrep3 | sed -n 's/.*Haplogrep 3 \([0-9.]\+\).*/\1/p': + type: eval + description: The expression to obtain the version of the tool + topics: versions: - - ${task.process}: @@ -53,9 +54,10 @@ topics: - haplogrep3: type: string description: The tool name - - haplogrep3 | sed -n 's/.*Haplogrep 3 \\([0-9.]\\+\\': - type: string - description: The command used to generate the version of the tool + - haplogrep3 | sed -n 's/.*Haplogrep 3 \([0-9.]\+\).*/\1/p': + type: eval + description: The expression to obtain the version of the tool + authors: - "@lucpen" maintainers: diff --git a/modules/nf-core/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml index 4a9086116a10..fb5cd93a0a84 100644 --- a/modules/nf-core/multiqc/meta.yml +++ b/modules/nf-core/multiqc/meta.yml @@ -80,9 +80,10 @@ output: - multiqc: type: string description: The tool name - - multiqc --version | sed "s/.* //g: - type: string - description: The command used to generate the version of the tool + - multiqc --version | sed "s/.* //g": + type: eval + description: The expression to obtain the version of the tool + topics: versions: - - ${task.process}: @@ -91,9 +92,10 @@ topics: - multiqc: type: string description: The tool name - - multiqc --version | sed "s/.* //g: - type: string - description: The command used to generate the version of the tool + - multiqc --version | sed "s/.* //g": + type: eval + description: The expression to obtain the version of the tool + authors: - "@abhi18av" - "@bunop" diff --git a/modules/nf-core/qsv/cat/meta.yml b/modules/nf-core/qsv/cat/meta.yml index f784da9e99c6..7ab11b6bda23 100644 --- a/modules/nf-core/qsv/cat/meta.yml +++ b/modules/nf-core/qsv/cat/meta.yml @@ -31,11 +31,13 @@ input: pattern: "^(rows|columns|rowskey)$" - out_format: type: string - description: Output format (.csv for comma delimiter, .ssv for semicolon, and .tsv or .tab for tab) + description: Output format (.csv for comma delimiter, .ssv for semicolon, + and .tsv or .tab for tab) pattern: "^(csv|ssv|tsv|tab)$" - skip_input_format_check: type: boolean - description: Skip input format check (by default QSV checks input format based on file extension) + description: Skip input format check (by default QSV checks input format + based on file extension) output: csv: - - meta: @@ -50,7 +52,7 @@ output: ontologies: - edam: http://edamontology.org/format_3752 # CSV - edam: http://edamontology.org/format_3475 # TSV - versions_qsv: &versions + versions_qsv: - - ${task.process}: type: string description: The name of the process @@ -61,7 +63,16 @@ output: type: eval description: The expression to obtain the version of the tool topics: - versions: *versions + versions: + - - ${task.process}: + type: string + description: The name of the process + - qsv: + type: string + description: The name of the tool + - "qsv --version | cut -d' ' -f2 | cut -d'-' -f1": + type: eval + description: The expression to obtain the version of the tool authors: - "@dialvarezs" maintainers: diff --git a/modules/nf-core/ribodetector/meta.yml b/modules/nf-core/ribodetector/meta.yml index 6599d45c8c5e..76d8f5c8774b 100644 --- a/modules/nf-core/ribodetector/meta.yml +++ b/modules/nf-core/ribodetector/meta.yml @@ -1,6 +1,6 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json name: "ribodetector" -description: Accurate and rapid RiboRNA sequences Detector based on deep learning +description: Accurate and rapid RiboRNA sequences Detector based on deep + learning keywords: - RNA - RNAseq @@ -14,12 +14,12 @@ keywords: - genomics tools: - ribodetector: - description: Accurate and rapid RiboRNA sequences detector based on deep learning. - RiboDetector uses a deep learning approach to identify rRNA sequences in ribosome - profiling (Ribo-seq) data. It can be used to filter out rRNA reads from Ribo-seq - datasets, improving the quality of downstream analyses. As of version 0.3.1, - Ribodetector doesn't support setting a random seed, so results may not be fully - deterministic across runs. + description: Accurate and rapid RiboRNA sequences detector based on deep + learning. RiboDetector uses a deep learning approach to identify rRNA + sequences in ribosome profiling (Ribo-seq) data. It can be used to filter + out rRNA reads from Ribo-seq datasets, improving the quality of downstream + analyses. As of version 0.3.1, Ribodetector doesn't support setting a + random seed, so results may not be fully deterministic across runs. homepage: "https://github.com/hzi-bifo/RiboDetector" documentation: "https://github.com/hzi-bifo/RiboDetector" tool_dev_url: "https://github.com/hzi-bifo/RiboDetector" @@ -73,9 +73,10 @@ output: - ribodetector: type: string description: Name of the tool - - ribodetector --version | sed "s/ribodetector //: - type: string - description: Version of ribodetector used + - ribodetector --version | sed "s/ribodetector //": + type: eval + description: The expression to obtain the version of the tool + topics: versions: - - ${task.process}: @@ -84,9 +85,10 @@ topics: - ribodetector: type: string description: Name of the tool - - ribodetector --version | sed "s/ribodetector //: - type: string - description: Version of ribodetector used + - ribodetector --version | sed "s/ribodetector //": + type: eval + description: The expression to obtain the version of the tool + authors: - "@maxibor" maintainers: diff --git a/modules/nf-core/samtools/sort/meta.yml b/modules/nf-core/samtools/sort/meta.yml index 809a57fcf4ba..6996830472e1 100644 --- a/modules/nf-core/samtools/sort/meta.yml +++ b/modules/nf-core/samtools/sort/meta.yml @@ -131,6 +131,7 @@ topics: - "samtools version | sed '1!d;s/.* //'": type: string description: The command used to generate the version of the tool + authors: - "@drpatelh" - "@ewels" diff --git a/modules/nf-core/samtools/stats/meta.yml b/modules/nf-core/samtools/stats/meta.yml index a20509ae60e6..5c59cce43182 100644 --- a/modules/nf-core/samtools/stats/meta.yml +++ b/modules/nf-core/samtools/stats/meta.yml @@ -62,21 +62,22 @@ output: - samtools: type: string description: Name of the tool - - samtools version | sed "1!d;s/.* //: - type: string - description: The command used to generate the version of the tool + - samtools version | sed "1!d;s/.* //": + type: eval + description: The expression to obtain the version of the tool topics: versions: - - ${task.process}: type: string - description: The process the versions were collected from + description: Name of the process - samtools: type: string - description: The tool name - - samtools version | sed "1!d;s/.* //: - type: string - description: The command used to generate the version of the tool + description: Name of the tool + - samtools version | sed "1!d;s/.* //": + type: eval + description: The expression to obtain the version of the tool + authors: - "@drpatelh" - "@FriederikeHanssen" diff --git a/modules/nf-core/samtools/view/meta.yml b/modules/nf-core/samtools/view/meta.yml index 3f9ad77fd2de..167206773bb4 100644 --- a/modules/nf-core/samtools/view/meta.yml +++ b/modules/nf-core/samtools/view/meta.yml @@ -147,9 +147,10 @@ output: - samtools: type: string description: Name of the tool - - samtools --version | head -1 | sed -e "s/samtools //: - type: string - description: Version of samtools used + - samtools --version | head -1 | sed -e "s/samtools //": + type: eval + description: The expression to obtain the version of the tool + topics: versions: - - ${task.process}: @@ -158,9 +159,10 @@ topics: - samtools: type: string description: Name of the tool - - samtools --version | head -1 | sed -e "s/samtools //: - type: string - description: Version of samtools used + - samtools --version | head -1 | sed -e "s/samtools //": + type: eval + description: The expression to obtain the version of the tool + authors: - "@drpatelh" - "@joseespinosa" diff --git a/modules/nf-core/semibin/singleeasybin/meta.yml b/modules/nf-core/semibin/singleeasybin/meta.yml index d60e9596aa92..3a7ffe1510e7 100644 --- a/modules/nf-core/semibin/singleeasybin/meta.yml +++ b/modules/nf-core/semibin/singleeasybin/meta.yml @@ -76,7 +76,7 @@ output: description: precluster fasta files pattern: "*.fa" ontologies: [] - versions_semibin: &versions + versions_semibin: - - ${task.process}: type: string description: The name of the process @@ -87,7 +87,16 @@ output: type: eval description: The expression to obtain the version of the tool topics: - versions: *versions + versions: + - - ${task.process}: + type: string + description: The name of the process + - SemiBin: + type: string + description: The name of the tool + - "SemiBin2 --version": + type: eval + description: The expression to obtain the version of the tool authors: - "@BigDataBiology" maintainers: diff --git a/modules/nf-core/strdrop/build/meta.yml b/modules/nf-core/strdrop/build/meta.yml index 64f47d2a34af..430a862dd340 100644 --- a/modules/nf-core/strdrop/build/meta.yml +++ b/modules/nf-core/strdrop/build/meta.yml @@ -62,6 +62,7 @@ topics: - strdrop --version | sed 's/.* //g': type: eval description: The expression to obtain the version of the tool + authors: - "@fellen31" maintainers: diff --git a/modules/nf-core/tabix/tabix/meta.yml b/modules/nf-core/tabix/tabix/meta.yml index 66de044ba291..f5b6b3c1604d 100644 --- a/modules/nf-core/tabix/tabix/meta.yml +++ b/modules/nf-core/tabix/tabix/meta.yml @@ -36,26 +36,28 @@ output: pattern: "*.{tbi,csi}" ontologies: [] versions_tabix: - - - "${task.process}": + - - ${task.process}: type: string description: The process the versions were collected from - - "tabix": + - tabix: type: string description: The tool name - - tabix -h 2>&1 | grep -oP 'Version:\\s*\\K[^\\s]+': - type: string - description: The command used to generate the version of the tool + - tabix -h 2>&1 | grep -oP 'Version:\s*\K[^\s]+': + type: eval + description: The expression to obtain the version of the tool + topics: versions: - - - "${task.process}": + - - ${task.process}: type: string description: The process the versions were collected from - - "tabix": + - tabix: type: string description: The tool name - - tabix -h 2>&1 | grep -oP 'Version:\\s*\\K[^\\s]+': - type: string - description: The command used to generate the version of the tool + - tabix -h 2>&1 | grep -oP 'Version:\s*\K[^\s]+': + type: eval + description: The expression to obtain the version of the tool + authors: - "@joseespinosa" - "@drpatelh" From 690f06712a38799a2dfc343e088bb3258f2b2efe Mon Sep 17 00:00:00 2001 From: Delfina Terradas <155591053+delfiterradas@users.noreply.github.com> Date: Tue, 9 Dec 2025 13:16:10 -0300 Subject: [PATCH 41/83] Fix dream to show more than 10 results (#9507) * fix: dream to show more than 10 results * test: update snapshots * test: update snapshots * feat: add round digits option and update snapshots again * fix: improve code formatting and update test snapshots * Fix tests and update snapshots * Update snapshot for `abundance_differential_filter` subworkflow * Fix tests with unstable content * Fix unstable files in test for `abundance_differential_filter` subworkflow --------- Co-authored-by: Anabella Trigila <18577080+atrigila@users.noreply.github.com> --- .../variancepartition/dream/templates/dream.R | 15 ++- .../dream/tests/main.nf.test | 47 ++++++-- .../dream/tests/main.nf.test.snap | 113 +++++------------- .../tests/dream.config | 8 ++ .../tests/main.nf.test | 8 +- .../tests/main.nf.test.snap | 86 ++++++------- 6 files changed, 137 insertions(+), 140 deletions(-) create mode 100644 subworkflows/nf-core/abundance_differential_filter/tests/dream.config diff --git a/modules/nf-core/variancepartition/dream/templates/dream.R b/modules/nf-core/variancepartition/dream/templates/dream.R index e46802d22f7c..aa582a7ef9ef 100644 --- a/modules/nf-core/variancepartition/dream/templates/dream.R +++ b/modules/nf-core/variancepartition/dream/templates/dream.R @@ -80,6 +80,7 @@ opt <- list( winsor_tail_p = "0.05,0.1", # Winsor tail probabilities for eBayes ddf = "adaptive", # 'Satterthwaite', 'Kenward-Roger', or 'adaptive' reml = FALSE, + round_digits = NULL, formula = "$formula", # User-specified formula (e.g. "~ + (1 | sample_number)") apply_voom = FALSE # Whether to apply `voomWithDreamWeights` ) @@ -107,6 +108,10 @@ opt\$p.value <- as.numeric(opt\$p.value) opt\$lfc <- as.numeric(opt\$lfc) opt\$confint <- as.logical(opt\$confint) +if (!is.null(opt\$round_digits)){ + opt\$round_digits <- as.numeric(opt\$round_digits) +} + # Load metadata metadata <- read_delim_flexible(opt\$sample_file, header = TRUE, stringsAsFactors = TRUE) rownames(metadata) <- metadata[[opt\$sample_id_col]] @@ -178,7 +183,7 @@ if (!is.null(opt\$contrast_string)) { stdev.coef.lim = stdev_coef_lim_vals, trend = opt\$trend, robust = opt\$robust, winsor.tail.p = winsor_tail_p_vals) - results <- topTable(fit2, + results <- topTable(fit2, number = Inf, adjust.method = opt\$adjust.method, p.value = opt\$p.value, lfc = opt\$lfc, confint = opt\$confint) @@ -186,7 +191,7 @@ if (!is.null(opt\$contrast_string)) { coef_name <- paste0(opt\$contrast_variable, opt\$contrast_target) cat("Using default contrast matrix:", coef_name, "\n") - results <- topTable(fitmm, coef = coef_name, + results <- topTable(fitmm, coef = coef_name, number = Inf, adjust.method = opt\$adjust.method, p.value = opt\$p.value, lfc = opt\$lfc, confint = opt\$confint) } @@ -194,6 +199,12 @@ if (!is.null(opt\$contrast_string)) { results\$gene_id <- rownames(results) results <- results[, c("gene_id", setdiff(names(results), "gene_id"))] +# Round results if required +if (!is.null(opt\$round_digits)) { + numeric_columns <- vapply(results, is.numeric, logical(1)) + results[numeric_columns] <- lapply(results[numeric_columns], round, digits = opt\$round_digits) +} + # Export topTable results write.table(results, file = paste(opt\$output_prefix, 'dream.results.tsv', sep = '.'), col.names = TRUE, row.names = FALSE, sep = '\t', quote = FALSE ) diff --git a/modules/nf-core/variancepartition/dream/tests/main.nf.test b/modules/nf-core/variancepartition/dream/tests/main.nf.test index aef4405e79fe..2b3fa0806c77 100644 --- a/modules/nf-core/variancepartition/dream/tests/main.nf.test +++ b/modules/nf-core/variancepartition/dream/tests/main.nf.test @@ -2,6 +2,7 @@ nextflow_process { name "Test Process VARIANCEPARTITION_DREAM" script "../main.nf" + config "./nextflow.config" process "VARIANCEPARTITION_DREAM" tag "modules" @@ -12,6 +13,9 @@ nextflow_process { test("RNAseq - Feature Counts - formula + comparison contrast string - interaction") { when { + params { + module_args = "--round_digits 2" + } process { """ input[0] = Channel.of([ @@ -40,8 +44,8 @@ nextflow_process { assertAll( { assert process.success }, { assert path(process.out.results[0][1]).getText().contains("gene_id\tlogFC\tAveExpr\tt\tP.Value\tadj.P.Val\tB") }, - { assert path(process.out.results[0][1]).getText().contains("0.8333") }, - { assert path(process.out.results[0][1]).getText().contains("13.5\t21.125\t4.40") }, + { assert path(process.out.results[0][1]).getText().contains("0.83") }, + { assert path(process.out.results[0][1]).getText().contains("13.5\t21.12\t4.41") }, { assert snapshot(process.out.model, process.out.versions).match() } ) } @@ -50,6 +54,9 @@ nextflow_process { test("Mus musculus - expression table - contrasts") { when { + params { + module_args = "--round_digits 2" + } process { """ input[0] = Channel.of(['id': 'treatment_mCherry_hND6', 'variable': 'treatment', 'reference': 'mCherry', 'target': 'hND6', 'blocking_factors':null, 'formula':null]) @@ -77,6 +84,9 @@ nextflow_process { test("Mus musculus - expression table - contrasts + formula + comparison contrast string") { when { + params { + module_args = "--round_digits 2" + } process { """ input[0] = Channel.of(['id': 'treatment_mCherry_hND6', 'variable': 'treatment', 'reference': 'mCherry', 'target': 'hND6', 'blocking_factors':'sample_number', 'formula':'~ treatment', 'comparison':'treatmenthND6']) @@ -98,9 +108,10 @@ nextflow_process { assertAll( { assert process.success }, { assert path(process.out.results[0][1]).getText().contains("gene_id\tlogFC\tAveExpr\tt\tP.Value\tadj.P.Val\tB") }, - { assert path(process.out.results[0][1]).getText().contains("849.6666") }, - { assert path(process.out.results[0][1]).getText().contains("1050\t549\t3.78") } - ) + { assert path(process.out.results[0][1]).getText().contains("849.67") }, + { assert path(process.out.results[0][1]).getText().contains("1050\t549\t3.78") }, + { assert snapshot(process.out.model, process.out.versions).match() } + ) } } @@ -108,6 +119,9 @@ nextflow_process { test("Mus musculus - expression table - contrasts + formula + weighted comparison contrast string") { when { + params { + module_args = "--round_digits 2" + } process { """ input[0] = Channel.of(['id': 'treatment_mCherry_hND6', 'variable': 'treatment', 'reference': 'mCherry', 'target': 'hND6', 'blocking_factors':'sample_number', 'formula':'~ 0 + treatment', 'comparison':'2 * treatmenthND6 - treatmentmCherry']) @@ -128,17 +142,20 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.model, process.out.versions).match() }, { assert path(process.out.results[0][1]).getText().contains("gene_id\tlogFC\tAveExpr\tt\tP.Value\tadj.P.Val\tB") }, - { assert path(process.out.results[0][1]).getText().contains("2124\t549\t4.83") }, - { assert path(process.out.results[0][1]).getText().contains("1707.33") } - ) + { assert path(process.out.results[0][1]).getText().contains("2124\t549\t4.84") }, + { assert path(process.out.results[0][1]).getText().contains("1707.33") }, + { assert snapshot(process.out.model, process.out.versions).match() } + ) } } test("Mus musculus - expression table - contrasts + formula + comparison contrast string - no intercept") { when { + params { + module_args = "--round_digits 2" + } process { """ input[0] = Channel.of(['id': 'treatment_mCherry_hND6', 'variable': 'treatment', 'reference': 'mCherry', 'target': 'hND6', 'blocking_factors':'sample_number', 'formula':'~ 0 + treatment + sample_number', 'comparison':'treatmenthND6 - treatmentmCherry']) @@ -161,15 +178,18 @@ nextflow_process { { assert process.success }, { assert snapshot(process.out.model, process.out.versions).match() }, { assert path(process.out.results[0][1]).getText().contains("gene_id\tlogFC\tAveExpr\tt\tP.Value\tadj.P.Val\tB") }, - { assert path(process.out.results[0][1]).getText().contains("-95.6666") }, - { assert path(process.out.results[0][1]).getText().contains("1050\t549\t4.15") } - ) + { assert path(process.out.results[0][1]).getText().contains("-95.67") }, + { assert path(process.out.results[0][1]).getText().contains("1050\t549\t4.16") } + ) } } test("Mus musculus - expression table - contrasts + blocking factors") { when { + params { + module_args = "--round_digits 2" + } process { """ input[0] = Channel.of(['id': 'treatment_mCherry_hND6', 'variable': 'treatment', 'reference': 'mCherry', 'target': 'hND6', 'blocking_factors':'sample_number', 'formula':'~ treatment + (1 | sample_number)']) @@ -199,6 +219,9 @@ nextflow_process { options '-stub' when { + params { + module_args = "--round_digits 2" + } process { """ input[0] = Channel.of(['id': 'treatment_mCherry_hND6', 'variable': 'treatment', 'reference': 'mCherry', 'target': 'hND6', 'blocking_factors':'sample_number', 'formula':'~ treatment + (1 | sample_number)']) diff --git a/modules/nf-core/variancepartition/dream/tests/main.nf.test.snap b/modules/nf-core/variancepartition/dream/tests/main.nf.test.snap index 08e677234d7a..a91efa5521cf 100644 --- a/modules/nf-core/variancepartition/dream/tests/main.nf.test.snap +++ b/modules/nf-core/variancepartition/dream/tests/main.nf.test.snap @@ -20,10 +20,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-11-10T16:15:40.192241719" + "timestamp": "2025-12-04T21:00:34.198143553" }, "RNAseq - Feature Counts - formula + comparison contrast string - interaction": { "content": [ @@ -46,10 +46,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-11-10T16:14:20.039981065" + "timestamp": "2025-12-04T20:59:55.416875311" }, "Mus musculus - expression table - contrasts + blocking factors": { "content": [ @@ -64,7 +64,7 @@ "blocking_factors": "sample_number", "formula": "~ treatment + (1 | sample_number)" }, - "treatment_mCherry_hND6.dream.results.tsv:md5,ad7e79a25bf407b210e3ebfbf734f68e" + "treatment_mCherry_hND6.dream.results.tsv:md5,df0717ddf702543c375c1a5f4eae3fd7" ] ], "1": [ @@ -106,7 +106,7 @@ "blocking_factors": "sample_number", "formula": "~ treatment + (1 | sample_number)" }, - "treatment_mCherry_hND6.dream.results.tsv:md5,ad7e79a25bf407b210e3ebfbf734f68e" + "treatment_mCherry_hND6.dream.results.tsv:md5,df0717ddf702543c375c1a5f4eae3fd7" ] ], "versions": [ @@ -115,10 +115,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-11-10T16:18:15.340812595" + "timestamp": "2025-12-04T19:20:24.632444115" }, "Mus musculus - expression table - contrasts + blocking factors stub": { "content": [ @@ -210,82 +210,35 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-11-10T16:15:20.824781388" + "timestamp": "2025-12-04T21:02:12.893838766" }, "Mus musculus - expression table - contrasts + formula + comparison contrast string": { "content": [ - { - "0": [ - [ - { - "id": "treatment_mCherry_hND6", - "variable": "treatment", - "reference": "mCherry", - "target": "hND6", - "blocking_factors": "sample_number", - "formula": "~ treatment", - "comparison": "treatmenthND6" - }, - "treatment_mCherry_hND6.dream.results.tsv:md5,0b9521f3aafdbc7f2df761bdc8b1a1ea" - ] - ], - "1": [ - [ - { - "id": "treatment_mCherry_hND6", - "variable": "treatment", - "reference": "mCherry", - "target": "hND6", - "blocking_factors": "sample_number", - "formula": "~ treatment", - "comparison": "treatmenthND6" - }, - "treatment_mCherry_hND6.dream.model.txt:md5,8cb944a29e3d3d0e540048b4d8331b17" - ] - ], - "2": [ - "versions.yml:md5,fc1f26eb2194018e99fc2916332676b7" - ], - "model": [ - [ - { - "id": "treatment_mCherry_hND6", - "variable": "treatment", - "reference": "mCherry", - "target": "hND6", - "blocking_factors": "sample_number", - "formula": "~ treatment", - "comparison": "treatmenthND6" - }, - "treatment_mCherry_hND6.dream.model.txt:md5,8cb944a29e3d3d0e540048b4d8331b17" - ] - ], - "results": [ - [ - { - "id": "treatment_mCherry_hND6", - "variable": "treatment", - "reference": "mCherry", - "target": "hND6", - "blocking_factors": "sample_number", - "formula": "~ treatment", - "comparison": "treatmenthND6" - }, - "treatment_mCherry_hND6.dream.results.tsv:md5,0b9521f3aafdbc7f2df761bdc8b1a1ea" - ] - ], - "versions": [ - "versions.yml:md5,fc1f26eb2194018e99fc2916332676b7" + [ + [ + { + "id": "treatment_mCherry_hND6", + "variable": "treatment", + "reference": "mCherry", + "target": "hND6", + "blocking_factors": "sample_number", + "formula": "~ treatment", + "comparison": "treatmenthND6" + }, + "treatment_mCherry_hND6.dream.model.txt:md5,8cb944a29e3d3d0e540048b4d8331b17" ] - } + ], + [ + "versions.yml:md5,fc1f26eb2194018e99fc2916332676b7" + ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-04-07T17:45:38.612858235" + "timestamp": "2025-12-04T21:02:02.754734146" } } \ No newline at end of file diff --git a/subworkflows/nf-core/abundance_differential_filter/tests/dream.config b/subworkflows/nf-core/abundance_differential_filter/tests/dream.config new file mode 100644 index 000000000000..5c96573c73f8 --- /dev/null +++ b/subworkflows/nf-core/abundance_differential_filter/tests/dream.config @@ -0,0 +1,8 @@ +process { + withName: 'VARIANCEPARTITION_DREAM' { + ext.args = { [ + "--round_digits 2" + ].join(' ').trim() } + ext.prefix = { "${meta.id}_${meta.differential_method}" } + } +} diff --git a/subworkflows/nf-core/abundance_differential_filter/tests/main.nf.test b/subworkflows/nf-core/abundance_differential_filter/tests/main.nf.test index 8f1d69fa127e..86bb1045735f 100644 --- a/subworkflows/nf-core/abundance_differential_filter/tests/main.nf.test +++ b/subworkflows/nf-core/abundance_differential_filter/tests/main.nf.test @@ -16,6 +16,7 @@ nextflow_workflow { tag "variancepartition/dream" test("dream") { + config './dream.config' tag "dream_simple" when { @@ -59,8 +60,8 @@ nextflow_workflow { then { assertAll( { assert workflow.success }, + { assert path(workflow.out.results_genewise[0][1]).getText().contains("gene_id\tlogFC\tAveExpr\tt\tP.Value\tadj.P.Val\tB") }, { assert snapshot( - workflow.out.results_genewise, workflow.out.results_genewise_filtered, workflow.out.model, workflow.out.versions @@ -70,6 +71,7 @@ nextflow_workflow { } test("dream - complex contrast - literal contrast string comparison") { + config './dream.config' tag "dream_complex" when { @@ -114,10 +116,8 @@ nextflow_workflow { assertAll( { assert workflow.success }, { assert path(workflow.out.results_genewise[0][1]).getText().contains("gene_id\tlogFC\tAveExpr\tt\tP.Value\tadj.P.Val\tB") }, - { assert path(workflow.out.results_genewise[0][1]).getText().contains("-95.6666") }, - { assert path(workflow.out.results_genewise[0][1]).getText().contains("1050\t549\t4.15") }, { assert snapshot( - file(workflow.out.results_genewise[0][1]).name, + workflow.out.results_genewise_filtered, workflow.out.model, workflow.out.versions ).match() } diff --git a/subworkflows/nf-core/abundance_differential_filter/tests/main.nf.test.snap b/subworkflows/nf-core/abundance_differential_filter/tests/main.nf.test.snap index adb73713d069..2bc8b96eae36 100644 --- a/subworkflows/nf-core/abundance_differential_filter/tests/main.nf.test.snap +++ b/subworkflows/nf-core/abundance_differential_filter/tests/main.nf.test.snap @@ -48,10 +48,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-06-17T10:30:52.112951" + "timestamp": "2025-12-04T21:34:41.609825626" }, "deseq2 and limma - mouse - basic": { "content": [ @@ -237,10 +237,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-06-17T10:38:20.375228" + "timestamp": "2025-12-04T21:36:19.869897897" }, "limma - voom": { "content": [ @@ -313,27 +313,13 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-06-17T10:31:18.015533" + "timestamp": "2025-12-04T21:34:54.342799115" }, "dream": { "content": [ - [ - [ - { - "id": "treatment_mCherry_hND6_test", - "variable": "treatment", - "reference": "mCherry", - "target": "hND6", - "blocking_factors": "sample_number", - "formula": "~ treatment + (1 | sample_number)", - "differential_method": "dream" - }, - "treatment_mCherry_hND6_test.dream.results.tsv:md5,ad7e79a25bf407b210e3ebfbf734f68e" - ] - ], [ [ { @@ -361,7 +347,7 @@ "formula": "~ treatment + (1 | sample_number)", "differential_method": "dream" }, - "treatment_mCherry_hND6_test.dream.model.txt:md5,7103206474aa480ffd9cec149263489f" + "treatment_mCherry_hND6_test_dream.dream.model.txt:md5,7103206474aa480ffd9cec149263489f" ] ], [ @@ -370,10 +356,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-07-04T21:27:14.641708892" + "timestamp": "2025-12-04T21:21:42.90174732" }, "deseq2 + limma-voom + propd - mouse - basic": { "content": [ @@ -633,9 +619,9 @@ ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.04.6" + "nextflow": "25.10.2" }, - "timestamp": "2025-10-29T15:08:57.424485" + "timestamp": "2025-12-04T21:37:02.640236928" }, "stub": { "content": [ @@ -961,14 +947,30 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-06-17T10:30:02.865825" + "timestamp": "2025-12-04T21:34:07.788482554" }, "dream - complex contrast - literal contrast string comparison": { "content": [ - "treatment_mCherry_hND6_test.dream.results.tsv", + [ + [ + { + "id": "treatment_mCherry_hND6_test", + "variable": "treatment", + "reference": "mCherry", + "target": "hND6", + "blocking_factors": "sample_number", + "formula": "~ 0 + treatment + sample_number", + "comparison": "treatmenthND6 - treatmentmCherry", + "differential_method": "dream", + "fc_threshold": 1.5, + "stat_threshold": 0.05 + }, + "treatment_mCherry_hND6_test_filtered.tsv:md5,0bfc9215edc6aad064c3ce6abc81bfce" + ] + ], [ [ { @@ -981,7 +983,7 @@ "comparison": "treatmenthND6 - treatmentmCherry", "differential_method": "dream" }, - "treatment_mCherry_hND6_test.dream.model.txt:md5,46fe9413749f1475edc6985647b0e4e1" + "treatment_mCherry_hND6_test_dream.dream.model.txt:md5,46fe9413749f1475edc6985647b0e4e1" ] ], [ @@ -990,10 +992,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-06-17T10:29:44.113003" + "timestamp": "2025-12-04T21:21:55.470042625" }, "deseq2 - with transcript lengths": { "content": [ @@ -1100,10 +1102,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-06-17T10:31:34.923988" + "timestamp": "2025-12-04T21:35:28.598725232" }, "propd - mouse - basic": { "content": [ @@ -1190,8 +1192,8 @@ ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.04.6" + "nextflow": "25.10.2" }, - "timestamp": "2025-10-29T15:07:36.308435" + "timestamp": "2025-12-04T21:35:43.634876525" } } \ No newline at end of file From 2b65b43dcf4ce749887527ccea4d6d8eaa30ee96 Mon Sep 17 00:00:00 2001 From: Evangelos Karatzas <32259775+vagkaratzas@users.noreply.github.com> Date: Tue, 9 Dec 2025 17:20:58 +0000 Subject: [PATCH 42/83] rename to more appropriate fastq_preprocess_seqkit (#9537) --- .../main.nf | 23 ++- .../meta.yml | 4 +- .../nextflow.config | 2 - .../tests/main.nf.test | 6 +- .../tests/main.nf.test.snap | 138 ++++++++++-------- .../tests/nextflow.config | 2 - 6 files changed, 92 insertions(+), 83 deletions(-) rename subworkflows/nf-core/{fastq_preprocess => fastq_preprocess_seqkit}/main.nf (81%) rename subworkflows/nf-core/{fastq_preprocess => fastq_preprocess_seqkit}/meta.yml (97%) rename subworkflows/nf-core/{fastq_preprocess => fastq_preprocess_seqkit}/nextflow.config (99%) rename subworkflows/nf-core/{fastq_preprocess => fastq_preprocess_seqkit}/tests/main.nf.test (97%) rename subworkflows/nf-core/{fastq_preprocess => fastq_preprocess_seqkit}/tests/main.nf.test.snap (59%) rename subworkflows/nf-core/{fastq_preprocess => fastq_preprocess_seqkit}/tests/nextflow.config (99%) diff --git a/subworkflows/nf-core/fastq_preprocess/main.nf b/subworkflows/nf-core/fastq_preprocess_seqkit/main.nf similarity index 81% rename from subworkflows/nf-core/fastq_preprocess/main.nf rename to subworkflows/nf-core/fastq_preprocess_seqkit/main.nf index 0b6ab8ce5f5c..ce0f4a5ad0d6 100644 --- a/subworkflows/nf-core/fastq_preprocess/main.nf +++ b/subworkflows/nf-core/fastq_preprocess_seqkit/main.nf @@ -3,22 +3,22 @@ include { SEQKIT_SEQ } from '../../../modules/nf-core/seqkit/seq/main include { SEQKIT_REPLACE } from '../../../modules/nf-core/seqkit/replace/main' include { SEQKIT_RMDUP } from '../../../modules/nf-core/seqkit/rmdup/main' -workflow FASTQ_PREPROCESS { +workflow FASTQ_PREPROCESS_SEQKIT { take: - ch_reads // channel: [ val(meta), [ fastq ] ] - skip_seqkit_sana_pair // boolean - skip_seqkit_seq // boolean - skip_seqkit_replace // boolean - skip_seqkit_rmdup // boolean + ch_reads // channel: [ val(meta), [ fastq ] ] + skip_seqkit_sana_pair // boolean + skip_seqkit_seq // boolean + skip_seqkit_replace // boolean + skip_seqkit_rmdup // boolean main: - ch_versions = Channel.empty() + ch_versions = channel.empty() if (!skip_seqkit_sana_pair) { FASTQ_SANITISE_SEQKIT( ch_reads ) - ch_reads = FASTQ_SANITISE_SEQKIT.out.reads - ch_versions = ch_versions.mix(FASTQ_SANITISE_SEQKIT.out.versions.first()) + ch_reads = FASTQ_SANITISE_SEQKIT.out.reads + ch_versions = ch_versions.mix(FASTQ_SANITISE_SEQKIT.out.versions) } // Split paired-end reads and add strandedness to meta @@ -75,7 +75,6 @@ workflow FASTQ_PREPROCESS { } emit: - reads = ch_reads // channel: [ val(meta), [ fastq ] ] - versions = ch_versions // channel: [ versions.yml ] - + reads = ch_reads // channel: [ val(meta), [ fastq ] ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/fastq_preprocess/meta.yml b/subworkflows/nf-core/fastq_preprocess_seqkit/meta.yml similarity index 97% rename from subworkflows/nf-core/fastq_preprocess/meta.yml rename to subworkflows/nf-core/fastq_preprocess_seqkit/meta.yml index 8cb30862e321..a3c6eaacbf74 100644 --- a/subworkflows/nf-core/fastq_preprocess/meta.yml +++ b/subworkflows/nf-core/fastq_preprocess_seqkit/meta.yml @@ -1,8 +1,8 @@ # yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json -name: "fastq_preprocess" +name: "fastq_preprocess_seqkit" description: Subworkflow that preprocesses FASTQ files keywords: - - fasta + - fastq - seqkit - preprocessing components: diff --git a/subworkflows/nf-core/fastq_preprocess/nextflow.config b/subworkflows/nf-core/fastq_preprocess_seqkit/nextflow.config similarity index 99% rename from subworkflows/nf-core/fastq_preprocess/nextflow.config rename to subworkflows/nf-core/fastq_preprocess_seqkit/nextflow.config index 0b0a68dd1d22..4e615588b706 100644 --- a/subworkflows/nf-core/fastq_preprocess/nextflow.config +++ b/subworkflows/nf-core/fastq_preprocess_seqkit/nextflow.config @@ -1,8 +1,6 @@ // IMPORTANT: This config file should be included to ensure that the subworkflow works properly. process { - withName: SEQKIT_SANA { ext.prefix = { "${meta.id}_${meta.strandness}" } } - } diff --git a/subworkflows/nf-core/fastq_preprocess/tests/main.nf.test b/subworkflows/nf-core/fastq_preprocess_seqkit/tests/main.nf.test similarity index 97% rename from subworkflows/nf-core/fastq_preprocess/tests/main.nf.test rename to subworkflows/nf-core/fastq_preprocess_seqkit/tests/main.nf.test index 44104ac2fc53..7b165120fab7 100644 --- a/subworkflows/nf-core/fastq_preprocess/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_preprocess_seqkit/tests/main.nf.test @@ -1,14 +1,14 @@ nextflow_workflow { - name "Test Subworkflow FASTQ_PREPROCESS" + name "Test Subworkflow FASTQ_PREPROCESS_SEQKIT" script "../main.nf" - workflow "FASTQ_PREPROCESS" + workflow "FASTQ_PREPROCESS_SEQKIT" config './nextflow.config' tag "subworkflows" tag "subworkflows_nfcore" tag "subworkflows/fastq_sanitise_seqkit" - tag "subworkflows/fastq_preprocess" + tag "subworkflows/fastq_preprocess_seqkit" tag "seqkit" tag "seqkit/sana" tag "seqkit/pair" diff --git a/subworkflows/nf-core/fastq_preprocess/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_preprocess_seqkit/tests/main.nf.test.snap similarity index 59% rename from subworkflows/nf-core/fastq_preprocess/tests/main.nf.test.snap rename to subworkflows/nf-core/fastq_preprocess_seqkit/tests/main.nf.test.snap index 920809ca126f..84e40272fa44 100644 --- a/subworkflows/nf-core/fastq_preprocess/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_preprocess_seqkit/tests/main.nf.test.snap @@ -12,10 +12,10 @@ ] ], "1": [ - "versions.yml:md5,12eff6cdaef31b58e36df720f8d96331", - "versions.yml:md5,8352db48172cddc55e42f943cdee1b9a", - "versions.yml:md5,9afc673105901c4307e8bb20d367a3ce", - "versions.yml:md5,d4403f4032d4cbb377d61ed83712253e" + "versions.yml:md5,39b373e11c89d8445dd09c9ae185e543", + "versions.yml:md5,adf5941e54371e92f795f80b8dc5abcd", + "versions.yml:md5,edb80840a6bf15376776a917a0f36216", + "versions.yml:md5,fe88ab8068d6a8284ee8a55f196f03e6" ], "reads": [ [ @@ -27,30 +27,30 @@ ] ], "versions": [ - "versions.yml:md5,12eff6cdaef31b58e36df720f8d96331", - "versions.yml:md5,8352db48172cddc55e42f943cdee1b9a", - "versions.yml:md5,9afc673105901c4307e8bb20d367a3ce", - "versions.yml:md5,d4403f4032d4cbb377d61ed83712253e" + "versions.yml:md5,39b373e11c89d8445dd09c9ae185e543", + "versions.yml:md5,adf5941e54371e92f795f80b8dc5abcd", + "versions.yml:md5,edb80840a6bf15376776a917a0f36216", + "versions.yml:md5,fe88ab8068d6a8284ee8a55f196f03e6" ] }, [ { - "FASTQ_PREPROCESS:SEQKIT_REPLACE": { + "FASTQ_PREPROCESS_SEQKIT:SEQKIT_REPLACE": { "seqkit": "2.9.0" } }, { - "FASTQ_PREPROCESS:SEQKIT_SEQ": { - "seqkit": "v2.9.0" + "FASTQ_PREPROCESS_SEQKIT:FASTQ_SANITISE_SEQKIT:SEQKIT_SANA": { + "seqkit": "2.10.1" } }, { - "FASTQ_PREPROCESS:FASTQ_SANITISE_SEQKIT:SEQKIT_SANA": { - "seqkit": "2.10.1" + "FASTQ_PREPROCESS_SEQKIT:SEQKIT_RMDUP": { + "seqkit": "v2.9.0" } }, { - "FASTQ_PREPROCESS:SEQKIT_RMDUP": { + "FASTQ_PREPROCESS_SEQKIT:SEQKIT_SEQ": { "seqkit": "v2.9.0" } } @@ -58,9 +58,9 @@ ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-10-29T13:17:10.915765" + "timestamp": "2025-12-09T16:30:14.034664087" }, "sarscov2 - fastq - single_end": { "content": [ @@ -75,10 +75,10 @@ ] ], "1": [ - "versions.yml:md5,12eff6cdaef31b58e36df720f8d96331", - "versions.yml:md5,8352db48172cddc55e42f943cdee1b9a", - "versions.yml:md5,9afc673105901c4307e8bb20d367a3ce", - "versions.yml:md5,d4403f4032d4cbb377d61ed83712253e" + "versions.yml:md5,39b373e11c89d8445dd09c9ae185e543", + "versions.yml:md5,adf5941e54371e92f795f80b8dc5abcd", + "versions.yml:md5,edb80840a6bf15376776a917a0f36216", + "versions.yml:md5,fe88ab8068d6a8284ee8a55f196f03e6" ], "reads": [ [ @@ -90,30 +90,30 @@ ] ], "versions": [ - "versions.yml:md5,12eff6cdaef31b58e36df720f8d96331", - "versions.yml:md5,8352db48172cddc55e42f943cdee1b9a", - "versions.yml:md5,9afc673105901c4307e8bb20d367a3ce", - "versions.yml:md5,d4403f4032d4cbb377d61ed83712253e" + "versions.yml:md5,39b373e11c89d8445dd09c9ae185e543", + "versions.yml:md5,adf5941e54371e92f795f80b8dc5abcd", + "versions.yml:md5,edb80840a6bf15376776a917a0f36216", + "versions.yml:md5,fe88ab8068d6a8284ee8a55f196f03e6" ] }, [ { - "FASTQ_PREPROCESS:SEQKIT_REPLACE": { + "FASTQ_PREPROCESS_SEQKIT:SEQKIT_REPLACE": { "seqkit": "2.9.0" } }, { - "FASTQ_PREPROCESS:SEQKIT_SEQ": { - "seqkit": "v2.9.0" + "FASTQ_PREPROCESS_SEQKIT:FASTQ_SANITISE_SEQKIT:SEQKIT_SANA": { + "seqkit": "2.10.1" } }, { - "FASTQ_PREPROCESS:FASTQ_SANITISE_SEQKIT:SEQKIT_SANA": { - "seqkit": "2.10.1" + "FASTQ_PREPROCESS_SEQKIT:SEQKIT_RMDUP": { + "seqkit": "v2.9.0" } }, { - "FASTQ_PREPROCESS:SEQKIT_RMDUP": { + "FASTQ_PREPROCESS_SEQKIT:SEQKIT_SEQ": { "seqkit": "v2.9.0" } } @@ -121,9 +121,9 @@ ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-10-29T13:16:51.34468" + "timestamp": "2025-12-09T16:29:39.447454093" }, "sarscov2 - fastq - paired_end": { "content": [ @@ -141,10 +141,11 @@ ] ], "1": [ - "versions.yml:md5,12eff6cdaef31b58e36df720f8d96331", - "versions.yml:md5,8352db48172cddc55e42f943cdee1b9a", - "versions.yml:md5,9afc673105901c4307e8bb20d367a3ce", - "versions.yml:md5,d4403f4032d4cbb377d61ed83712253e" + "versions.yml:md5,29f612df1ac521c317aff0d7950e2ed6", + "versions.yml:md5,39b373e11c89d8445dd09c9ae185e543", + "versions.yml:md5,adf5941e54371e92f795f80b8dc5abcd", + "versions.yml:md5,edb80840a6bf15376776a917a0f36216", + "versions.yml:md5,fe88ab8068d6a8284ee8a55f196f03e6" ], "reads": [ [ @@ -159,30 +160,36 @@ ] ], "versions": [ - "versions.yml:md5,12eff6cdaef31b58e36df720f8d96331", - "versions.yml:md5,8352db48172cddc55e42f943cdee1b9a", - "versions.yml:md5,9afc673105901c4307e8bb20d367a3ce", - "versions.yml:md5,d4403f4032d4cbb377d61ed83712253e" + "versions.yml:md5,29f612df1ac521c317aff0d7950e2ed6", + "versions.yml:md5,39b373e11c89d8445dd09c9ae185e543", + "versions.yml:md5,adf5941e54371e92f795f80b8dc5abcd", + "versions.yml:md5,edb80840a6bf15376776a917a0f36216", + "versions.yml:md5,fe88ab8068d6a8284ee8a55f196f03e6" ] }, [ { - "FASTQ_PREPROCESS:SEQKIT_REPLACE": { + "FASTQ_PREPROCESS_SEQKIT:FASTQ_SANITISE_SEQKIT:SEQKIT_PAIR": { "seqkit": "2.9.0" } }, { - "FASTQ_PREPROCESS:SEQKIT_SEQ": { - "seqkit": "v2.9.0" + "FASTQ_PREPROCESS_SEQKIT:SEQKIT_REPLACE": { + "seqkit": "2.9.0" } }, { - "FASTQ_PREPROCESS:FASTQ_SANITISE_SEQKIT:SEQKIT_SANA": { + "FASTQ_PREPROCESS_SEQKIT:FASTQ_SANITISE_SEQKIT:SEQKIT_SANA": { "seqkit": "2.10.1" } }, { - "FASTQ_PREPROCESS:SEQKIT_RMDUP": { + "FASTQ_PREPROCESS_SEQKIT:SEQKIT_RMDUP": { + "seqkit": "v2.9.0" + } + }, + { + "FASTQ_PREPROCESS_SEQKIT:SEQKIT_SEQ": { "seqkit": "v2.9.0" } } @@ -190,9 +197,9 @@ ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-10-29T13:16:58.073323" + "timestamp": "2025-12-09T16:29:51.089592083" }, "sarscov2 - fastq - both with single broken": { "content": [ @@ -217,10 +224,11 @@ ] ], "1": [ - "versions.yml:md5,12eff6cdaef31b58e36df720f8d96331", - "versions.yml:md5,8352db48172cddc55e42f943cdee1b9a", - "versions.yml:md5,9afc673105901c4307e8bb20d367a3ce", - "versions.yml:md5,d4403f4032d4cbb377d61ed83712253e" + "versions.yml:md5,29f612df1ac521c317aff0d7950e2ed6", + "versions.yml:md5,39b373e11c89d8445dd09c9ae185e543", + "versions.yml:md5,adf5941e54371e92f795f80b8dc5abcd", + "versions.yml:md5,edb80840a6bf15376776a917a0f36216", + "versions.yml:md5,fe88ab8068d6a8284ee8a55f196f03e6" ], "reads": [ [ @@ -242,30 +250,36 @@ ] ], "versions": [ - "versions.yml:md5,12eff6cdaef31b58e36df720f8d96331", - "versions.yml:md5,8352db48172cddc55e42f943cdee1b9a", - "versions.yml:md5,9afc673105901c4307e8bb20d367a3ce", - "versions.yml:md5,d4403f4032d4cbb377d61ed83712253e" + "versions.yml:md5,29f612df1ac521c317aff0d7950e2ed6", + "versions.yml:md5,39b373e11c89d8445dd09c9ae185e543", + "versions.yml:md5,adf5941e54371e92f795f80b8dc5abcd", + "versions.yml:md5,edb80840a6bf15376776a917a0f36216", + "versions.yml:md5,fe88ab8068d6a8284ee8a55f196f03e6" ] }, [ { - "FASTQ_PREPROCESS:SEQKIT_REPLACE": { + "FASTQ_PREPROCESS_SEQKIT:FASTQ_SANITISE_SEQKIT:SEQKIT_PAIR": { "seqkit": "2.9.0" } }, { - "FASTQ_PREPROCESS:SEQKIT_SEQ": { - "seqkit": "v2.9.0" + "FASTQ_PREPROCESS_SEQKIT:SEQKIT_REPLACE": { + "seqkit": "2.9.0" } }, { - "FASTQ_PREPROCESS:FASTQ_SANITISE_SEQKIT:SEQKIT_SANA": { + "FASTQ_PREPROCESS_SEQKIT:FASTQ_SANITISE_SEQKIT:SEQKIT_SANA": { "seqkit": "2.10.1" } }, { - "FASTQ_PREPROCESS:SEQKIT_RMDUP": { + "FASTQ_PREPROCESS_SEQKIT:SEQKIT_RMDUP": { + "seqkit": "v2.9.0" + } + }, + { + "FASTQ_PREPROCESS_SEQKIT:SEQKIT_SEQ": { "seqkit": "v2.9.0" } } @@ -273,8 +287,8 @@ ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-10-29T13:17:05.485679" + "timestamp": "2025-12-09T16:30:03.379196661" } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_preprocess/tests/nextflow.config b/subworkflows/nf-core/fastq_preprocess_seqkit/tests/nextflow.config similarity index 99% rename from subworkflows/nf-core/fastq_preprocess/tests/nextflow.config rename to subworkflows/nf-core/fastq_preprocess_seqkit/tests/nextflow.config index 97438b00ba0d..78045d7d3e04 100644 --- a/subworkflows/nf-core/fastq_preprocess/tests/nextflow.config +++ b/subworkflows/nf-core/fastq_preprocess_seqkit/tests/nextflow.config @@ -1,5 +1,4 @@ process { - withName: SEQKIT_SANA { ext.prefix = { "${meta.id}_${meta.strandness}" } } @@ -24,5 +23,4 @@ process { withName: SEQKIT_RMDUP { ext.prefix = { "${meta.id}_${meta.strandness}" } } - } From 08f0cec0774fbd4900cac3822db1bc0403337e34 Mon Sep 17 00:00:00 2001 From: Sameesh Kher Date: Tue, 9 Dec 2025 18:48:15 +0100 Subject: [PATCH 43/83] New module - TD2 (added modules for td2.longorfs & td2.predict) (#9475) * added modules for td2.longorfs & td2.predict * changes to version handling, updated snaps, and tests - resolving comments * added topics section in meta.yml * fix topics section in meta.yml * Update modules/nf-core/td2/longorfs/main.nf Co-authored-by: Simon Pearce <24893913+SPPearce@users.noreply.github.com> * Update modules/nf-core/td2/longorfs/meta.yml Co-authored-by: Simon Pearce <24893913+SPPearce@users.noreply.github.com> * Update modules/nf-core/td2/predict/main.nf Co-authored-by: Simon Pearce <24893913+SPPearce@users.noreply.github.com> * Update modules/nf-core/td2/longorfs/meta.yml Co-authored-by: Simon Pearce <24893913+SPPearce@users.noreply.github.com> * Update main.nf - stub run * Update meta.yml * resolving comments * updated emad ontologies * Update modules/nf-core/td2/predict/tests/main.nf.test.snap * Update modules/nf-core/td2/predict/main.nf * Update modules/nf-core/td2/longorfs/tests/main.nf.test.snap * Update modules/nf-core/td2/longorfs/main.nf * Update modules/nf-core/td2/predict/tests/main.nf.test.snap * Update modules/nf-core/td2/longorfs/tests/main.nf.test.snap --------- Co-authored-by: Simon Pearce <24893913+SPPearce@users.noreply.github.com> --- modules/nf-core/td2/longorfs/environment.yml | 5 + modules/nf-core/td2/longorfs/main.nf | 43 ++++++ modules/nf-core/td2/longorfs/meta.yml | 71 ++++++++++ .../nf-core/td2/longorfs/tests/main.nf.test | 64 +++++++++ .../td2/longorfs/tests/main.nf.test.snap | 62 +++++++++ modules/nf-core/td2/predict/environment.yml | 5 + modules/nf-core/td2/predict/main.nf | 47 +++++++ modules/nf-core/td2/predict/meta.yml | 77 +++++++++++ .../nf-core/td2/predict/tests/main.nf.test | 79 ++++++++++++ .../td2/predict/tests/main.nf.test.snap | 122 ++++++++++++++++++ 10 files changed, 575 insertions(+) create mode 100644 modules/nf-core/td2/longorfs/environment.yml create mode 100644 modules/nf-core/td2/longorfs/main.nf create mode 100644 modules/nf-core/td2/longorfs/meta.yml create mode 100644 modules/nf-core/td2/longorfs/tests/main.nf.test create mode 100644 modules/nf-core/td2/longorfs/tests/main.nf.test.snap create mode 100644 modules/nf-core/td2/predict/environment.yml create mode 100644 modules/nf-core/td2/predict/main.nf create mode 100644 modules/nf-core/td2/predict/meta.yml create mode 100644 modules/nf-core/td2/predict/tests/main.nf.test create mode 100644 modules/nf-core/td2/predict/tests/main.nf.test.snap diff --git a/modules/nf-core/td2/longorfs/environment.yml b/modules/nf-core/td2/longorfs/environment.yml new file mode 100644 index 000000000000..db97153a88db --- /dev/null +++ b/modules/nf-core/td2/longorfs/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::td2=1.0.6" diff --git a/modules/nf-core/td2/longorfs/main.nf b/modules/nf-core/td2/longorfs/main.nf new file mode 100644 index 000000000000..addfcd06c454 --- /dev/null +++ b/modules/nf-core/td2/longorfs/main.nf @@ -0,0 +1,43 @@ +process TD2_LONGORFS { + tag "$meta.id" + label 'process_medium' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/41/4155bf3b720e1e32d0615a947696fb0287ee4e8cdbeb4ec784dd4da7bb5b2e86/data': + "community.wave.seqera.io/library/td2:1.0.6--ea3e5ac09443b677"}" + + input: + tuple val(meta), path(fasta) + + output: + tuple val(meta), path("${prefix}/longest_orfs.{cds,gff3,pep}"), emit: orfs + tuple val("${task.process}"), val('TD2.LongOrfs'), eval("echo ${VERSION}"), emit: versions_td2, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + VERSION = '1.0.6' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + prefix = task.ext.prefix ?: "${meta.id}" + + """ + TD2.LongOrfs \\ + -t ${fasta} \\ + -O ${prefix} \\ + --threads ${task.cpus} \\ + ${args} + """ + + stub: + VERSION = 'v1.0.6' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + prefix = task.ext.prefix ?: "${meta.id}" + + """ + mkdir -p ${prefix}/ + touch ${prefix}/longest_orfs.cds + touch ${prefix}/longest_orfs.gff3 + touch ${prefix}/longest_orfs.pep + """ +} diff --git a/modules/nf-core/td2/longorfs/meta.yml b/modules/nf-core/td2/longorfs/meta.yml new file mode 100644 index 000000000000..5c14180aab5d --- /dev/null +++ b/modules/nf-core/td2/longorfs/meta.yml @@ -0,0 +1,71 @@ +name: "td2_longorfs" +description: TD2 identifies candidate coding regions within transcript + sequences, such as those generated by de novo RNA-Seq transcript assembly +keywords: + - td2 + - orfs + - longorfs + - transcripts +tools: + - td2: + description: "TD2 identifies candidate coding regions within transcript sequences, + such as those generated by de novo RNA-Seq transcript assembly" + homepage: "https://github.com/Markusjsommer/TD2" + documentation: "https://github.com/Markusjsommer/TD2" + tool_dev_url: "https://github.com/Markusjsommer/TD2" + licence: ["MIT"] + identifier: "" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - fasta: + type: file + description: Fasta file containing the target transcript sequences + pattern: "*.{fasta}" + ontologies: + - edam: http://edamontology.org/format_1929 # FASTA +output: + orfs: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - ${prefix}/longest_orfs.{cds,gff3,pep}: + type: file + description: Files containing the longest ORFs predicted from the input + transcript sequences + pattern: "${prefix}/longest_orfs.{cds,gff3,pep}" + ontologies: + - edam: http://edamontology.org/format_1929 # FASTA + - edam: http://edamontology.org/format_1975 # GFF3 + - edam: http://edamontology.org/format_1960 # Protein FASTA + versions_td2: + - - ${task.process}: + type: string + description: The process the versions were collected from + - TD2.LongOrfs: + type: string + description: The tool name + - echo ${VERSION}: + type: string + description: The tool version +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - TD2.LongOrfs: + type: string + description: The tool name + - echo ${VERSION}: + type: string + description: The tool version +authors: + - "@khersameesh24" +maintainers: + - "@khersameesh24" diff --git a/modules/nf-core/td2/longorfs/tests/main.nf.test b/modules/nf-core/td2/longorfs/tests/main.nf.test new file mode 100644 index 000000000000..cb677922fe9f --- /dev/null +++ b/modules/nf-core/td2/longorfs/tests/main.nf.test @@ -0,0 +1,64 @@ +nextflow_process { + + name "Test Process TD2_LONGORFS" + script "../main.nf" + process "TD2_LONGORFS" + + tag "modules" + tag "modules_nfcore" + tag "td2" + tag "td2/longorfs" + + test("td2.longorfs - transcriptome.fasta") { + + when { + process { + """ + input[0] = [ + [ id:'test_td2_longorfs' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/transcriptome.fasta', checkIfExists: true), + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out.orfs, + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } + + test("td2.longorfs - transcriptome.fasta -stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test_td2_longorfs' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/transcriptome.fasta', checkIfExists: true), + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out.orfs, + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } + +} diff --git a/modules/nf-core/td2/longorfs/tests/main.nf.test.snap b/modules/nf-core/td2/longorfs/tests/main.nf.test.snap new file mode 100644 index 000000000000..fd4f752a19a8 --- /dev/null +++ b/modules/nf-core/td2/longorfs/tests/main.nf.test.snap @@ -0,0 +1,62 @@ +{ + "td2.longorfs - transcriptome.fasta": { + "content": [ + [ + [ + { + "id": "test_td2_longorfs" + }, + [ + "longest_orfs.cds:md5,4226fe196a4527f938e25061ffe7eaf6", + "longest_orfs.gff3:md5,864ae9147b65d07eb9d79c0e42968e12", + "longest_orfs.pep:md5,0151dac6998be924139a4f5a5a0c590b" + ] + ] + ], + { + "versions_td2": [ + [ + "TD2_LONGORFS", + "TD2.LongOrfs", + "1.0.6" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-08T22:55:17.67412706" + }, + "td2.longorfs - transcriptome.fasta -stub": { + "content": [ + [ + [ + { + "id": "test_td2_longorfs" + }, + [ + "longest_orfs.cds:md5,d41d8cd98f00b204e9800998ecf8427e", + "longest_orfs.gff3:md5,d41d8cd98f00b204e9800998ecf8427e", + "longest_orfs.pep:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + { + "versions_td2": [ + [ + "TD2_LONGORFS", + "TD2.LongOrfs", + "1.0.6" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-08T22:57:07.433423015" + } +} \ No newline at end of file diff --git a/modules/nf-core/td2/predict/environment.yml b/modules/nf-core/td2/predict/environment.yml new file mode 100644 index 000000000000..db97153a88db --- /dev/null +++ b/modules/nf-core/td2/predict/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::td2=1.0.6" diff --git a/modules/nf-core/td2/predict/main.nf b/modules/nf-core/td2/predict/main.nf new file mode 100644 index 000000000000..cefd23653e2f --- /dev/null +++ b/modules/nf-core/td2/predict/main.nf @@ -0,0 +1,47 @@ +process TD2_PREDICT { + tag "$meta.id" + label 'process_medium' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/41/4155bf3b720e1e32d0615a947696fb0287ee4e8cdbeb4ec784dd4da7bb5b2e86/data': + "community.wave.seqera.io/library/td2:1.0.6--ea3e5ac09443b677"}" + + input: + tuple val(meta), path(fasta), path(orfs_dir, stageAs: 'orfs') + + output: + tuple val(meta), path("${prefix}/*.TD2.{bed,cds,gff3,pep}") , emit: predictions + tuple val("${task.process}"), val('TD2.Predict'), eval("echo ${VERSION}"), emit: versions_td2, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + VERSION = '1.0.6' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + prefix = task.ext.prefix ?: "${meta.id}" + + """ + mkdir -p ${prefix}/ + + TD2.Predict \\ + -t ${fasta} \\ + -O ${orfs_dir} \\ + ${args} + + mv *.TD2.{bed,cds,gff3,pep} ${prefix}/ + """ + + stub: + VERSION = 'v1.0.6' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + prefix = task.ext.prefix ?: "${meta.id}" + + """ + mkdir -p ${prefix}/ + touch ${prefix}/${fasta}.TD2.bed + touch ${prefix}/${fasta}.TD2.cds + touch ${prefix}/${fasta}.TD2.gff3 + touch ${prefix}/${fasta}.TD2.pep + """ +} diff --git a/modules/nf-core/td2/predict/meta.yml b/modules/nf-core/td2/predict/meta.yml new file mode 100644 index 000000000000..2bc7995573ae --- /dev/null +++ b/modules/nf-core/td2/predict/meta.yml @@ -0,0 +1,77 @@ +name: "td2_predict" +description: TD2 identifies candidate coding regions within transcript + sequences, such as those generated by de novo RNA-Seq transcript assembly +keywords: + - predict + - orfs + - coding regions + - td2.predict +tools: + - "td2": + description: "TD2 identifies candidate coding regions within transcript sequences, + such as those generated by de novo RNA-Seq transcript assembly" + homepage: "https://github.com/Markusjsommer/TD2" + documentation: "https://github.com/Markusjsommer/TD2" + tool_dev_url: "https://github.com/Markusjsommer/TD2" + licence: ["MIT"] + identifier: "" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - fasta: + type: file + description: Transcripts fasta file + pattern: "*.fasta" + ontologies: + - edam: http://edamontology.org/format_1929 # FASTA + - orfs_dir: + type: file + description: Directory containing the ORF prediction files generated by + the `td2_longorfs` module + pattern: "orfs_dir/" + ontologies: [] +output: + predictions: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - ${prefix}/*.TD2.{bed,cds,gff3,pep}: + type: file + description: Files containing the TD2 ORF predictions for the input + transcript sequences + pattern: "${prefix}/*.TD2.{bed,cds,gff3,pep}" + ontologies: + - edam: http://edamontology.org/format_3003 # BED + - edam: http://edamontology.org/format_1929 # FASTA + - edam: http://edamontology.org/format_1975 # GFF3 + versions_td2: + - - ${task.process}: + type: string + description: The process the versions were collected from + - TD2.Predict: + type: string + description: The tool name + - echo ${VERSION}: + type: string + description: The tool version +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - TD2.Predict: + type: string + description: The tool name + - echo ${VERSION}: + type: string + description: The tool version +authors: + - "@khersameesh24" +maintainers: + - "@khersameesh24" diff --git a/modules/nf-core/td2/predict/tests/main.nf.test b/modules/nf-core/td2/predict/tests/main.nf.test new file mode 100644 index 000000000000..4f3bb30eda27 --- /dev/null +++ b/modules/nf-core/td2/predict/tests/main.nf.test @@ -0,0 +1,79 @@ +nextflow_process { + + name "Test Process TD2_PREDICT" + script "../main.nf" + process "TD2_PREDICT" + + tag "modules" + tag "modules_nfcore" + tag "td2" + tag "td2/longorfs" + tag "td2/predict" + + setup { + run("TD2_LONGORFS") { + script "modules/nf-core/td2/longorfs/main.nf" + process { + """ + input[0] = [ + [id:'test_td2_predict'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + } + + test("td2.predict - transcriptome.fasta") { + + when { + process { + """ + input[0] = Channel.of([ + [id: 'test_td2_predict'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ]).combine(TD2_LONGORFS.out.orfs.map{ meta, orfs -> return [meta, file(orfs[0].getParent())] }, by: 0) + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out, + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } + + test("td2.predict - transcriptome.fasta - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [id: 'test_td2_predict'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ]).combine(TD2_LONGORFS.out.orfs.map{ meta, orfs -> return [meta, file(orfs[0].getParent())] }, by: 0) + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out, + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + + } + +} diff --git a/modules/nf-core/td2/predict/tests/main.nf.test.snap b/modules/nf-core/td2/predict/tests/main.nf.test.snap new file mode 100644 index 000000000000..30f62d67d6dc --- /dev/null +++ b/modules/nf-core/td2/predict/tests/main.nf.test.snap @@ -0,0 +1,122 @@ +{ + "td2.predict - transcriptome.fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test_td2_predict" + }, + [ + "genome.fasta.TD2.bed:md5,2504559bdf4e321bc0612573be0a1eb6", + "genome.fasta.TD2.cds:md5,e3f601c2ab4e9513b6577bbcdc19fda5", + "genome.fasta.TD2.gff3:md5,0e4fd0095da808937192caee48fe47d5", + "genome.fasta.TD2.pep:md5,390c241ee523756f3cd81b3cf2fa62ac" + ] + ] + ], + "1": [ + [ + "TD2_PREDICT", + "TD2.Predict", + "1.0.6" + ] + ], + "predictions": [ + [ + { + "id": "test_td2_predict" + }, + [ + "genome.fasta.TD2.bed:md5,2504559bdf4e321bc0612573be0a1eb6", + "genome.fasta.TD2.cds:md5,e3f601c2ab4e9513b6577bbcdc19fda5", + "genome.fasta.TD2.gff3:md5,0e4fd0095da808937192caee48fe47d5", + "genome.fasta.TD2.pep:md5,390c241ee523756f3cd81b3cf2fa62ac" + ] + ] + ], + "versions_td2": [ + [ + "TD2_PREDICT", + "TD2.Predict", + "v1.0.6" + ] + ] + }, + { + "versions_td2": [ + [ + "TD2_PREDICT", + "TD2.Predict", + "1.0.6" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-08T22:59:14.906163868" + }, + "td2.predict - transcriptome.fasta - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test_td2_predict" + }, + [ + "genome.fasta.TD2.bed:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.TD2.cds:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.TD2.gff3:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.TD2.pep:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + [ + "TD2_PREDICT", + "TD2.Predict", + "v1.0.6" + ] + ], + "predictions": [ + [ + { + "id": "test_td2_predict" + }, + [ + "genome.fasta.TD2.bed:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.TD2.cds:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.TD2.gff3:md5,d41d8cd98f00b204e9800998ecf8427e", + "genome.fasta.TD2.pep:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_td2": [ + [ + "TD2_PREDICT", + "TD2.Predict", + "v1.0.6" + ] + ] + }, + { + "versions_td2": [ + [ + "TD2_PREDICT", + "TD2.Predict", + "v1.0.6" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-08T23:01:07.402304947" + } +} \ No newline at end of file From 8293491bad8ed6e7fdbabd7f36ad352d96971f99 Mon Sep 17 00:00:00 2001 From: Luca Beltrame Date: Wed, 10 Dec 2025 07:43:45 +0100 Subject: [PATCH 44/83] Bump ichorCNA package build in ichorcna/createpon and ichorcna/run (#9531) * Bump ichorCNA package build in ichorcna/createpon and ichorcna/run At the moment, creating a PoN without data on chromosome X is bound to fail due to a bug in ichorCNA(https://github.com/GavinHaLab/ichorCNA/pull/26). It is unclear when a new version will be out, so I have patched the current bioconda package (https://github.com/bioconda/bioconda-recipes/pull/61045) and built new container images, which I want to update to in this PR. * Update some md5sums * Update test snapshot * Update test snapshot --- .../nf-core/ichorcna/createpon/environment.yml | 2 +- modules/nf-core/ichorcna/createpon/main.nf | 4 ++-- .../ichorcna/createpon/tests/main.nf.test.snap | 18 +++++++++--------- modules/nf-core/ichorcna/run/environment.yml | 2 +- modules/nf-core/ichorcna/run/main.nf | 4 ++-- .../ichorcna/run/tests/main.nf.test.snap | 12 ++++++------ 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/modules/nf-core/ichorcna/createpon/environment.yml b/modules/nf-core/ichorcna/createpon/environment.yml index 54df91b4f291..5073fc577927 100644 --- a/modules/nf-core/ichorcna/createpon/environment.yml +++ b/modules/nf-core/ichorcna/createpon/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::r-ichorcna=0.5.1 + - bioconda::r-ichorcna=0.5.1=r44hdfd78af_1 diff --git a/modules/nf-core/ichorcna/createpon/main.nf b/modules/nf-core/ichorcna/createpon/main.nf index ab19a0332c25..3be817e0c2cd 100644 --- a/modules/nf-core/ichorcna/createpon/main.nf +++ b/modules/nf-core/ichorcna/createpon/main.nf @@ -3,8 +3,8 @@ process ICHORCNA_CREATEPON { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/r-ichorcna:0.5.1--r43hdfd78af_0' : - 'biocontainers/r-ichorcna:0.5.1--r43hdfd78af_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f0/f07cec06705b4443052d3d7eaccebdbd0078366f7d074bfd4a6893980c6e2c4b/data' : + 'community.wave.seqera.io/library/r-ichorcna:0.5.1--eed4be826f05c9d4' }" input: path wigs diff --git a/modules/nf-core/ichorcna/createpon/tests/main.nf.test.snap b/modules/nf-core/ichorcna/createpon/tests/main.nf.test.snap index fe73d2efe9ac..4a2615ab0452 100644 --- a/modules/nf-core/ichorcna/createpon/tests/main.nf.test.snap +++ b/modules/nf-core/ichorcna/createpon/tests/main.nf.test.snap @@ -4,21 +4,21 @@ "PoN_median.rds", "PoN_median.txt", [ - "versions.yml:md5,59dbc83520b9e00a736f49ed2513657a" + "versions.yml:md5,4a4f8b452427ec9438cf0ffad62c7a7d" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-08-06T14:23:09.884294332" + "timestamp": "2025-12-09T11:34:25.04737792" }, "stub": { "content": [ "PoN.rds", "PoN.txt", [ - "versions.yml:md5,59dbc83520b9e00a736f49ed2513657a" + "versions.yml:md5,4a4f8b452427ec9438cf0ffad62c7a7d" ] ], "meta": { @@ -32,13 +32,13 @@ "PoN_median.rds", "PoN_median.txt", [ - "versions.yml:md5,59dbc83520b9e00a736f49ed2513657a" + "versions.yml:md5,4a4f8b452427ec9438cf0ffad62c7a7d" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-08-06T14:23:29.496424481" + "timestamp": "2025-12-09T11:34:34.559159568" } } \ No newline at end of file diff --git a/modules/nf-core/ichorcna/run/environment.yml b/modules/nf-core/ichorcna/run/environment.yml index 54df91b4f291..5073fc577927 100644 --- a/modules/nf-core/ichorcna/run/environment.yml +++ b/modules/nf-core/ichorcna/run/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::r-ichorcna=0.5.1 + - bioconda::r-ichorcna=0.5.1=r44hdfd78af_1 diff --git a/modules/nf-core/ichorcna/run/main.nf b/modules/nf-core/ichorcna/run/main.nf index 68cf302fc1b9..f8fd2eea3a2e 100644 --- a/modules/nf-core/ichorcna/run/main.nf +++ b/modules/nf-core/ichorcna/run/main.nf @@ -4,8 +4,8 @@ process ICHORCNA_RUN { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/r-ichorcna:0.5.1--r43hdfd78af_0' : - 'biocontainers/r-ichorcna:0.5.1--r43hdfd78af_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f0/f07cec06705b4443052d3d7eaccebdbd0078366f7d074bfd4a6893980c6e2c4b/data' : + 'community.wave.seqera.io/library/r-ichorcna:0.5.1--eed4be826f05c9d4' }" input: tuple val(meta), path(wig) diff --git a/modules/nf-core/ichorcna/run/tests/main.nf.test.snap b/modules/nf-core/ichorcna/run/tests/main.nf.test.snap index 7a70f7bd51d1..13e21009b585 100644 --- a/modules/nf-core/ichorcna/run/tests/main.nf.test.snap +++ b/modules/nf-core/ichorcna/run/tests/main.nf.test.snap @@ -67,7 +67,7 @@ ] ], "8": [ - "versions.yml:md5,d2d30cedd49c7bffdcb74313e8a074c4" + "versions.yml:md5,0395d992ef3e4aa41ed95603f461cc92" ], "cna_seg": [ [ @@ -134,20 +134,20 @@ ] ], "versions": [ - "versions.yml:md5,d2d30cedd49c7bffdcb74313e8a074c4" + "versions.yml:md5,0395d992ef3e4aa41ed95603f461cc92" ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-08-02T06:38:13.140234725" + "timestamp": "2025-12-09T11:32:23.125027221" }, "no_panel": { "content": [ [ - "versions.yml:md5,d2d30cedd49c7bffdcb74313e8a074c4" + "versions.yml:md5,0395d992ef3e4aa41ed95603f461cc92" ], "test_genomeWide.pdf", "test.RData", From a78cc001fd9737fbd6b582f8d365959e0897697a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rayan=20Hassa=C3=AFne?= Date: Wed, 10 Dec 2025 10:06:12 +0100 Subject: [PATCH 45/83] RSeQC split_bam.py module implementation (#9536) * RSeQC split_bam.py module implementation Syntax edit Refractored version channel to topic Cleanup * Update modules/nf-core/rseqc/splitbam/main.nf Co-authored-by: Felix Lenner <52530259+fellen31@users.noreply.github.com> * Update modules/nf-core/rseqc/splitbam/tests/main.nf.test Co-authored-by: Felix Lenner <52530259+fellen31@users.noreply.github.com> * Update modules/nf-core/rseqc/splitbam/tests/main.nf.test Co-authored-by: Felix Lenner <52530259+fellen31@users.noreply.github.com> * Updated snapshot --------- Co-authored-by: Felix Lenner <52530259+fellen31@users.noreply.github.com> Co-authored-by: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> --- .../nf-core/rseqc/splitbam/environment.yml | 7 + modules/nf-core/rseqc/splitbam/main.nf | 42 +++++ modules/nf-core/rseqc/splitbam/meta.yml | 111 +++++++++++++ .../nf-core/rseqc/splitbam/tests/main.nf.test | 72 +++++++++ .../rseqc/splitbam/tests/main.nf.test.snap | 148 ++++++++++++++++++ 5 files changed, 380 insertions(+) create mode 100644 modules/nf-core/rseqc/splitbam/environment.yml create mode 100644 modules/nf-core/rseqc/splitbam/main.nf create mode 100644 modules/nf-core/rseqc/splitbam/meta.yml create mode 100644 modules/nf-core/rseqc/splitbam/tests/main.nf.test create mode 100644 modules/nf-core/rseqc/splitbam/tests/main.nf.test.snap diff --git a/modules/nf-core/rseqc/splitbam/environment.yml b/modules/nf-core/rseqc/splitbam/environment.yml new file mode 100644 index 000000000000..6cdb911dd007 --- /dev/null +++ b/modules/nf-core/rseqc/splitbam/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::rseqc=5.0.4" diff --git a/modules/nf-core/rseqc/splitbam/main.nf b/modules/nf-core/rseqc/splitbam/main.nf new file mode 100644 index 000000000000..0b6c3f0d5187 --- /dev/null +++ b/modules/nf-core/rseqc/splitbam/main.nf @@ -0,0 +1,42 @@ +process RSEQC_SPLITBAM { + tag "$meta.id" + label 'process_medium' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/rseqc:5.0.4--pyhdfd78af_1' : + 'biocontainers/rseqc:5.0.4--pyhdfd78af_1' }" + + input: + tuple val(meta) , path(bam), path(bai) + tuple val(meta2), path(bed) + + output: + tuple val(meta), path("*.in.bam") , emit: in_bam + tuple val(meta), path("*.ex.bam") , emit: ex_bam + tuple val(meta), path("*.junk.bam"), emit: junk_bam + tuple val("${task.process}"), val('rseqc'), eval('split_bam.py --version | sed "s/split_bam.py //"'), emit: versions_rseqc, topic: versions + + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + split_bam.py \\ + -i $bam \\ + -r $bed \\ + -o $prefix \\ + $args + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.in.bam + touch ${prefix}.ex.bam + touch ${prefix}.junk.bam + """ +} diff --git a/modules/nf-core/rseqc/splitbam/meta.yml b/modules/nf-core/rseqc/splitbam/meta.yml new file mode 100644 index 000000000000..e907d09609a8 --- /dev/null +++ b/modules/nf-core/rseqc/splitbam/meta.yml @@ -0,0 +1,111 @@ +name: rseqc_splitbam +description: Split BAM file based on gene list in BED format +keywords: + - bam + - split + - rnaseq + - quality control +tools: + - "rseqc": + description: | + RSeQC package provides a number of useful modules that can comprehensively evaluate + high throughput sequence data especially RNA-seq data. + homepage: "http://rseqc.sourceforge.net/" + documentation: "http://rseqc.sourceforge.net/" + tool_dev_url: "https://github.com/MonashBioinformaticsPlatform/RSeQC" + doi: "10.1093/bioinformatics/bts356" + licence: ["GPL-3.0-or-later"] + identifier: biotools:rseqc + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - bam: + type: file + description: Sorted BAM file + pattern: "*.{bam}" + ontologies: + - edam: "http://edamontology.org/format_2572" # BAM + - bai: + type: file + description: BAM index file + pattern: "*.{bai}" + ontologies: + - edam: "http://edamontology.org/format_3327" # BAI + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. `[ id:'reference' ]` + - bed: + type: file + description: Gene list in BED format to split the BAM by + pattern: "*.{bed}" + ontologies: + - edam: "http://edamontology.org/format_3003" # BED + +output: + in_bam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.in.bam": + type: file + description: BAM file containing reads that mapped to the gene list + pattern: "*.in.bam" + ontologies: + - edam: "http://edamontology.org/format_2572" # BAM + ex_bam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.ex.bam": + type: file + description: BAM file containing reads that did not map to the gene list + pattern: "*.ex.bam" + ontologies: + - edam: "http://edamontology.org/format_2572" # BAM + junk_bam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.junk.bam": + type: file + description: BAM file containing QC failed or unmapped reads + pattern: "*.junk.bam" + ontologies: + - edam: "http://edamontology.org/format_2572" # BAM + versions_rseqc: + - - ${task.process}: + type: string + description: The process the versions were collected from + - rseqc: + type: string + description: The tool name + - split_bam.py --version | sed "s/split_bam.py //": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - rseqc: + type: string + description: The tool name + - split_bam.py --version | sed "s/split_bam.py //": + type: eval + description: The expression to obtain the version of the tool +authors: + - "@rhassaine" +maintainers: + - "@rhassaine" diff --git a/modules/nf-core/rseqc/splitbam/tests/main.nf.test b/modules/nf-core/rseqc/splitbam/tests/main.nf.test new file mode 100644 index 000000000000..87b80f2943f6 --- /dev/null +++ b/modules/nf-core/rseqc/splitbam/tests/main.nf.test @@ -0,0 +1,72 @@ +nextflow_process { + + name "Test Process RSEQC_SPLITBAM" + script "../main.nf" + process "RSEQC_SPLITBAM" + + tag "modules" + tag "modules_nfcore" + tag "rseqc" + tag "rseqc/splitbam" + + test("sarscov2 - [[meta] - bam - bai] - [[meta2] - bed]") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai", checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'test_bed' ], // meta2 map + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/bed/test.bed12", checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out + ).match() } + ) + } + + } + + test("sarscov2 - [[meta] - bam - bai] - [[meta2] - bed] - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai", checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'test_bed' ], // meta2 map + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/bed/test.bed12", checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out + ).match() } + ) + } + + } + +} diff --git a/modules/nf-core/rseqc/splitbam/tests/main.nf.test.snap b/modules/nf-core/rseqc/splitbam/tests/main.nf.test.snap new file mode 100644 index 000000000000..4d83f7131288 --- /dev/null +++ b/modules/nf-core/rseqc/splitbam/tests/main.nf.test.snap @@ -0,0 +1,148 @@ +{ + "sarscov2 - [[meta] - bam - bai] - [[meta2] - bed] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.in.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.ex.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test" + }, + "test.junk.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + "RSEQC_SPLITBAM", + "rseqc", + "5.0.4" + ] + ], + "ex_bam": [ + [ + { + "id": "test" + }, + "test.ex.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "in_bam": [ + [ + { + "id": "test" + }, + "test.in.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "junk_bam": [ + [ + { + "id": "test" + }, + "test.junk.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_rseqc": [ + [ + "RSEQC_SPLITBAM", + "rseqc", + "5.0.4" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T08:52:06.92323219" + }, + "sarscov2 - [[meta] - bam - bai] - [[meta2] - bed]": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.in.bam:md5,1b683a36569410a655b2c2cd5312a9de" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.ex.bam:md5,de1a667ed02b677907c441792a9fd651" + ] + ], + "2": [ + [ + { + "id": "test" + }, + "test.junk.bam:md5,db5d68a1eef108c6bef2090beb0941bd" + ] + ], + "3": [ + [ + "RSEQC_SPLITBAM", + "rseqc", + "5.0.4" + ] + ], + "ex_bam": [ + [ + { + "id": "test" + }, + "test.ex.bam:md5,de1a667ed02b677907c441792a9fd651" + ] + ], + "in_bam": [ + [ + { + "id": "test" + }, + "test.in.bam:md5,1b683a36569410a655b2c2cd5312a9de" + ] + ], + "junk_bam": [ + [ + { + "id": "test" + }, + "test.junk.bam:md5,db5d68a1eef108c6bef2090beb0941bd" + ] + ], + "versions_rseqc": [ + [ + "RSEQC_SPLITBAM", + "rseqc", + "5.0.4" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T08:52:00.227785889" + } +} \ No newline at end of file From 56445cb3b156e43d5af6bc775da77f753029a484 Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> Date: Wed, 10 Dec 2025 10:44:21 +0100 Subject: [PATCH 46/83] remove topics from multiqc (#9530) * remove topics from multiqc * versions_multiqc -> versions * Apply suggestion from @nvnieuwk * fix meta.yml after merge --- modules/nf-core/multiqc/main.nf | 4 ++-- modules/nf-core/multiqc/meta.yml | 20 ++++--------------- .../nf-core/multiqc/tests/main.nf.test.snap | 12 +++++------ 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 335afccc4ab2..82f89795e4e4 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -18,7 +18,8 @@ process MULTIQC { path "*.html" , emit: report path "*_data" , emit: data path "*_plots" , optional:true, emit: plots - tuple val("${task.process}"), val('multiqc'), eval('multiqc --version | sed "s/.* //g"'), topic: versions, emit: versions_multiqc + tuple val("${task.process}"), val('multiqc'), eval('multiqc --version | sed "s/.* //g"'), emit: versions + // MultiQC should not push its versions to the `versions` topic. Its input depends on the versions topic to be resolved thus outputting to the topic will let the pipeline hang forever when: task.ext.when == null || task.ext.when @@ -50,6 +51,5 @@ process MULTIQC { touch multiqc_data/.stub mkdir multiqc_plots touch multiqc_report.html - """ } diff --git a/modules/nf-core/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml index fb5cd93a0a84..e4b8f94ddc9c 100644 --- a/modules/nf-core/multiqc/meta.yml +++ b/modules/nf-core/multiqc/meta.yml @@ -1,6 +1,6 @@ name: multiqc -description: Aggregate results from bioinformatics analyses across many samples - into a single report +description: Aggregate results from bioinformatics analyses across many samples into + a single report keywords: - QC - bioinformatics tools @@ -28,8 +28,8 @@ input: - edam: http://edamontology.org/format_3750 # YAML - extra_multiqc_config: type: file - description: Second optional config yml for MultiQC. Will override common - sections in multiqc_config. + description: Second optional config yml for MultiQC. Will override common sections + in multiqc_config. pattern: "*.{yml,yaml}" ontologies: - edam: http://edamontology.org/format_3750 # YAML @@ -73,18 +73,6 @@ output: description: Plots created by MultiQC pattern: "*_data" ontologies: [] - versions_multiqc: - - - ${task.process}: - type: string - description: The process the versions were collected from - - multiqc: - type: string - description: The tool name - - multiqc --version | sed "s/.* //g": - type: eval - description: The expression to obtain the version of the tool - -topics: versions: - - ${task.process}: type: string diff --git a/modules/nf-core/multiqc/tests/main.nf.test.snap b/modules/nf-core/multiqc/tests/main.nf.test.snap index f76049d3b410..3a8ce6b55685 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test.snap +++ b/modules/nf-core/multiqc/tests/main.nf.test.snap @@ -2,7 +2,7 @@ "sarscov2 single-end [fastqc]": { "content": [ { - "versions_multiqc": [ + "versions": [ [ "MULTIQC", "multiqc", @@ -15,7 +15,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-28T15:27:59.813370216" + "timestamp": "2025-12-09T10:10:43.020315838" }, "sarscov2 single-end [fastqc] - stub": { "content": [ @@ -24,7 +24,7 @@ "multiqc_data", "multiqc_plots", { - "versions_multiqc": [ + "versions": [ [ "MULTIQC", "multiqc", @@ -38,12 +38,12 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-28T15:30:48.963962021" + "timestamp": "2025-12-09T10:11:14.131950776" }, "sarscov2 single-end [fastqc] [config]": { "content": [ { - "versions_multiqc": [ + "versions": [ [ "MULTIQC", "multiqc", @@ -56,6 +56,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-10-28T15:29:30.664969334" + "timestamp": "2025-12-09T10:11:07.15692209" } } \ No newline at end of file From 66d0bdd93b9a3d2034e87636e1a316a8e9cec537 Mon Sep 17 00:00:00 2001 From: Friederike Hanssen Date: Wed, 10 Dec 2025 11:12:15 +0100 Subject: [PATCH 47/83] bump to MultiQC version 1.33 (#9538) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * bump to 1.33 * update snapshots --------- Co-authored-by: Matthias Hörtenhuber --- modules/nf-core/multiqc/environment.yml | 2 +- modules/nf-core/multiqc/main.nf | 4 ++-- .../nf-core/multiqc/tests/main.nf.test.snap | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/nf-core/multiqc/environment.yml b/modules/nf-core/multiqc/environment.yml index d02016a0090a..009874d4c002 100644 --- a/modules/nf-core/multiqc/environment.yml +++ b/modules/nf-core/multiqc/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::multiqc=1.32 + - bioconda::multiqc=1.33 diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 82f89795e4e4..3b0e975be6c8 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -3,8 +3,8 @@ process MULTIQC { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/8c/8c6c120d559d7ee04c7442b61ad7cf5a9e8970be5feefb37d68eeaa60c1034eb/data' : - 'community.wave.seqera.io/library/multiqc:1.32--d58f60e4deb769bf' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/34/34e733a9ae16a27e80fe00f863ea1479c96416017f24a907996126283e7ecd4d/data' : + 'community.wave.seqera.io/library/multiqc:1.33--ee7739d47738383b' }" input: path multiqc_files, stageAs: "?/*" diff --git a/modules/nf-core/multiqc/tests/main.nf.test.snap b/modules/nf-core/multiqc/tests/main.nf.test.snap index 3a8ce6b55685..d72d35b74737 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test.snap +++ b/modules/nf-core/multiqc/tests/main.nf.test.snap @@ -6,14 +6,14 @@ [ "MULTIQC", "multiqc", - "1.32" + "1.33" ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, "timestamp": "2025-12-09T10:10:43.020315838" }, @@ -28,15 +28,15 @@ [ "MULTIQC", "multiqc", - "1.32" + "1.33" ] ] } ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, "timestamp": "2025-12-09T10:11:14.131950776" }, @@ -47,14 +47,14 @@ [ "MULTIQC", "multiqc", - "1.32" + "1.33" ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, "timestamp": "2025-12-09T10:11:07.15692209" } From f3f9582e97417f2b6f3d1843a99d26d37b0a553c Mon Sep 17 00:00:00 2001 From: Felix Lenner <52530259+fellen31@users.noreply.github.com> Date: Wed, 10 Dec 2025 13:36:42 +0100 Subject: [PATCH 48/83] Add strdrop/call (#9513) * Add strdrop build * Add strdrop/call * remove tag * fix wrong parameter name in error * align * remove duplicate versions * snaps * figure out why snapshots are not stable * different versions of trgt used in setup --- modules/nf-core/strdrop/call/environment.yml | 10 + modules/nf-core/strdrop/call/main.nf | 51 +++++ modules/nf-core/strdrop/call/meta.yml | 90 ++++++++ .../nf-core/strdrop/call/tests/main.nf.test | 209 ++++++++++++++++++ .../strdrop/call/tests/main.nf.test.snap | 166 ++++++++++++++ 5 files changed, 526 insertions(+) create mode 100644 modules/nf-core/strdrop/call/environment.yml create mode 100644 modules/nf-core/strdrop/call/main.nf create mode 100644 modules/nf-core/strdrop/call/meta.yml create mode 100644 modules/nf-core/strdrop/call/tests/main.nf.test create mode 100644 modules/nf-core/strdrop/call/tests/main.nf.test.snap diff --git a/modules/nf-core/strdrop/call/environment.yml b/modules/nf-core/strdrop/call/environment.yml new file mode 100644 index 000000000000..6bb6e068535a --- /dev/null +++ b/modules/nf-core/strdrop/call/environment.yml @@ -0,0 +1,10 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - conda-forge::pip=25.3 + - conda-forge::python=3.14.1 + - pip: + - strdrop==0.3 diff --git a/modules/nf-core/strdrop/call/main.nf b/modules/nf-core/strdrop/call/main.nf new file mode 100644 index 000000000000..2eafb6e82c54 --- /dev/null +++ b/modules/nf-core/strdrop/call/main.nf @@ -0,0 +1,51 @@ +process STRDROP_CALL { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/4f/4fc3114f6d67fadb826981d29ae67f8564ee81283184893c2db677d919b5b32d/data': + 'community.wave.seqera.io/library/pip_strdrop:df8d5dc993ea6848' }" + + input: + tuple val(meta), path(vcf) + tuple val(meta2), path(training_set_json) + tuple val(meta3), path(training_set_vcfs, stageAs: 'input/*') + + output: + tuple val(meta), path("*.vcf.gz"), emit: vcf + tuple val("${task.process}"), val('strdrop'), eval("strdrop --version | sed 's/.* //g'"), topic: versions, emit: versions_strdrop + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def training_set = training_set_json ? "--training-set ${training_set_json}" : '--training-set ./input' + + if (training_set_json && training_set_vcfs) { + error("Please provide only one of 'training_set_json' or 'training_set_vcfs' as training set input.") + } + """ + strdrop \\ + call \\ + $args \\ + $training_set \\ + $vcf \\ + ${prefix}.vcf.gz + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + if (training_set_json && training_set_vcfs) { + error("Please provide only one of 'training_set_json' or 'training_set_vcfs' as training set input.") + } + """ + echo $args + + echo | gzip > ${prefix}.vcf.gz + """ +} diff --git a/modules/nf-core/strdrop/call/meta.yml b/modules/nf-core/strdrop/call/meta.yml new file mode 100644 index 000000000000..c05cdf308e3f --- /dev/null +++ b/modules/nf-core/strdrop/call/meta.yml @@ -0,0 +1,90 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "strdrop_call" +description: Detect drops in STR coverage +keywords: + - str + - vcf + - lrs +tools: + - "strdrop": + description: "Flag STR coverage drops in LRS data" + homepage: "https://github.com/dnil/strdrop" + documentation: "https://github.com/dnil/strdrop/blob/main/docs/README.md" + tool_dev_url: "https://github.com/dnil/strdrop" + licence: ["MIT"] + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - vcf: + type: file + description: Input STR call VCF file + pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" + ontologies: + - edam: "http://edamontology.org/format_3016" # VCF + - edam: "http://edamontology.org/format_3020" # BCF + - - meta2: + type: map + description: | + Groovy Map containing training set information + e.g. `[ id:'sample1' ]` + - training_set_json: + type: file + description: Input training set as json + pattern: "*.json" + ontologies: + - edam: "http://edamontology.org/format_3464" # JSON + - - meta3: + type: map + description: | + Groovy Map containing training set information + e.g. `[ id:'sample1' ]` + - training_set_vcfs: + type: file + description: Input training set as VCF files + pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" + ontologies: + - edam: "http://edamontology.org/format_3016" # VCF + - edam: "http://edamontology.org/format_3020" # BCF +output: + vcf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.vcf.gz": + type: file + description: Output annotated VCF file + pattern: "*.{vcf.gz}" + ontologies: + - edam: "http://edamontology.org/format_3016" # VCF + versions_strdrop: + - - "${task.process}": + type: string + description: The name of the process + - "strdrop": + type: string + description: The name of the tool + - "strdrop --version | sed 's/.* //g'": + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - strdrop: + type: string + description: The name of the tool + - strdrop --version | sed 's/.* //g': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@fellen31" +maintainers: + - "@fellen31" diff --git a/modules/nf-core/strdrop/call/tests/main.nf.test b/modules/nf-core/strdrop/call/tests/main.nf.test new file mode 100644 index 000000000000..90044e01376f --- /dev/null +++ b/modules/nf-core/strdrop/call/tests/main.nf.test @@ -0,0 +1,209 @@ +nextflow_process { + + name "Test Process STRDROP_CALL" + script "../main.nf" + process "STRDROP_CALL" + + tag "modules" + tag "modules_nfcore" + tag "strdrop" + tag "strdrop/call" + tag "samtools/faidx" + tag "gunzip" + tag "trgt/genotype" + tag "strdrop/build" + + setup { + run("GUNZIP"){ + script "../../../gunzip/main.nf" + process { + """ + input[0] = [ + [ id : 'chr22' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22_chr22_KI270734v1_random/sequence/genome.fa.gz', checkIfExists: true) + ] + """ + } + } + run("SAMTOOLS_FAIDX"){ + script "../../../samtools/faidx/main.nf" + process { + """ + input[0] = GUNZIP.out.gunzip + input[1] = [[],[]] + input[2] = false + """ + } + } + run("TRGT_GENOTYPE"){ + script "../../../trgt/genotype/main.nf" + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/bam/test.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/bam/test.sorted.bam.bai', checkIfExists: true), + 'XX' + ] + input[1] = GUNZIP.out.gunzip + input[2] = SAMTOOLS_FAIDX.out.fai + input[3] = Channel.of('chr22\t18890357\t18890451\tID=TEST;MOTIFS=AT;STRUC=(AT)n') + .collectFile(name : 'repeats.bed', newLine: false) + .map { file -> [ [ id : 'chr22' ], file ] } + """ + } + } + run("STRDROP_BUILD"){ + script "../../../strdrop/build/main.nf" + process { + """ + input[0] = TRGT_GENOTYPE.out.vcf + """ + } + } + } + + test("json-input") { + + when { + process { + """ + input[0] = TRGT_GENOTYPE.out.vcf + .map { meta, vcf -> + [ [id:'input'], vcf ] + } + input[1] = STRDROP_BUILD.out.json + input[2] = [[],[]] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + + } + + test("vcf-input") { + + when { + process { + """ + input[0] = TRGT_GENOTYPE.out.vcf + .map { meta, vcf -> + [ [id:'input'], vcf ] + } + input[1] = [[],[]] + input[2] = TRGT_GENOTYPE.out.vcf + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + + } + + test("vcf-json-input") { + + when { + process { + """ + input[0] = TRGT_GENOTYPE.out.vcf + .map { meta, vcf -> + [ [id:'input'], vcf ] + } + input[1] = STRDROP_BUILD.out.json + input[2] = TRGT_GENOTYPE.out.vcf + """ + } + } + + then { + assert process.failed + } + + } + + test("json-input-stub") { + + options "-stub" + + when { + process { + """ + input[0] = TRGT_GENOTYPE.out.vcf + .map { meta, vcf -> + [ [id:'input'], vcf ] + } + input[1] = STRDROP_BUILD.out.json + input[2] = [[],[]] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + + } + + test("vcf-input-stub") { + + options "-stub" + + when { + process { + """ + input[0] = TRGT_GENOTYPE.out.vcf + .map { meta, vcf -> + [ [id:'input'], vcf ] + } + input[1] = [[],[]] + input[2] = TRGT_GENOTYPE.out.vcf + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(process.out).match() } + ) + } + + } + + test("vcf-json-input-stub") { + + options "-stub" + + when { + process { + """ + input[0] = TRGT_GENOTYPE.out.vcf + .map { meta, vcf -> + [ [id:'input'], vcf ] + } + input[1] = STRDROP_BUILD.out.json + input[2] = TRGT_GENOTYPE.out.vcf + """ + } + } + + then { + assert process.failed + } + + } +} diff --git a/modules/nf-core/strdrop/call/tests/main.nf.test.snap b/modules/nf-core/strdrop/call/tests/main.nf.test.snap new file mode 100644 index 000000000000..12d5982fb3ff --- /dev/null +++ b/modules/nf-core/strdrop/call/tests/main.nf.test.snap @@ -0,0 +1,166 @@ +{ + "vcf-input-stub": { + "content": [ + { + "0": [ + [ + { + "id": "input" + }, + "input.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + "STRDROP_CALL", + "strdrop", + "0.3" + ] + ], + "vcf": [ + [ + { + "id": "input" + }, + "input.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_strdrop": [ + [ + "STRDROP_CALL", + "strdrop", + "0.3" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-10T09:27:39.835472209" + }, + "vcf-input": { + "content": [ + { + "0": [ + [ + { + "id": "input" + }, + "input.vcf.gz:md5,cc4a260ddb9e6b0fe5b481d478b27bf9" + ] + ], + "1": [ + [ + "STRDROP_CALL", + "strdrop", + "0.3" + ] + ], + "vcf": [ + [ + { + "id": "input" + }, + "input.vcf.gz:md5,cc4a260ddb9e6b0fe5b481d478b27bf9" + ] + ], + "versions_strdrop": [ + [ + "STRDROP_CALL", + "strdrop", + "0.3" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-10T13:28:07.339844531" + }, + "json-input": { + "content": [ + { + "0": [ + [ + { + "id": "input" + }, + "input.vcf.gz:md5,cc4a260ddb9e6b0fe5b481d478b27bf9" + ] + ], + "1": [ + [ + "STRDROP_CALL", + "strdrop", + "0.3" + ] + ], + "vcf": [ + [ + { + "id": "input" + }, + "input.vcf.gz:md5,cc4a260ddb9e6b0fe5b481d478b27bf9" + ] + ], + "versions_strdrop": [ + [ + "STRDROP_CALL", + "strdrop", + "0.3" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-10T13:28:01.066159827" + }, + "json-input-stub": { + "content": [ + { + "0": [ + [ + { + "id": "input" + }, + "input.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + "STRDROP_CALL", + "strdrop", + "0.3" + ] + ], + "vcf": [ + [ + { + "id": "input" + }, + "input.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_strdrop": [ + [ + "STRDROP_CALL", + "strdrop", + "0.3" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-10T09:27:33.984895465" + } +} \ No newline at end of file From 0bac4f643ae5f40e3ce83737e2bff8723b4a3faf Mon Sep 17 00:00:00 2001 From: Felix Lenner <52530259+fellen31@users.noreply.github.com> Date: Wed, 10 Dec 2025 14:12:59 +0100 Subject: [PATCH 49/83] Bump TRGT to 5.0.0 (#9541) 5.0.0 --- modules/nf-core/trgt/genotype/environment.yml | 2 +- modules/nf-core/trgt/genotype/main.nf | 4 +- .../trgt/genotype/tests/main.nf.test.snap | 48 +++++++++---------- modules/nf-core/trgt/merge/environment.yml | 2 +- modules/nf-core/trgt/merge/main.nf | 4 +- .../trgt/merge/tests/main.nf.test.snap | 26 +++++----- modules/nf-core/trgt/plot/environment.yml | 2 +- modules/nf-core/trgt/plot/main.nf | 4 +- .../nf-core/trgt/plot/tests/main.nf.test.snap | 8 ++-- 9 files changed, 50 insertions(+), 50 deletions(-) diff --git a/modules/nf-core/trgt/genotype/environment.yml b/modules/nf-core/trgt/genotype/environment.yml index 5ff336d40646..3a5bdd3bf721 100644 --- a/modules/nf-core/trgt/genotype/environment.yml +++ b/modules/nf-core/trgt/genotype/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::trgt=4.1.0 + - bioconda::trgt=5.0.0 diff --git a/modules/nf-core/trgt/genotype/main.nf b/modules/nf-core/trgt/genotype/main.nf index 1fe75f7d60de..f3fe81ac9bca 100644 --- a/modules/nf-core/trgt/genotype/main.nf +++ b/modules/nf-core/trgt/genotype/main.nf @@ -4,8 +4,8 @@ process TRGT_GENOTYPE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/trgt:4.1.0--h9ee0642_0': - 'biocontainers/trgt:4.1.0--h9ee0642_0' }" + 'https://depot.galaxyproject.org/singularity/trgt:5.0.0--h9ee0642_0': + 'biocontainers/trgt:5.0.0--h9ee0642_0' }" input: tuple val(meta) , path(bam), path(bai), val(karyotype) diff --git a/modules/nf-core/trgt/genotype/tests/main.nf.test.snap b/modules/nf-core/trgt/genotype/tests/main.nf.test.snap index 70dd85f39bbd..0e616172e97e 100644 --- a/modules/nf-core/trgt/genotype/tests/main.nf.test.snap +++ b/modules/nf-core/trgt/genotype/tests/main.nf.test.snap @@ -7,7 +7,7 @@ { "id": "test" }, - "test.vcf.gz:md5,cb694061956ddcd63772baf9a0720624" + "test.vcf.gz:md5,791ad621617ff0e7eab5892404d17592" ] ], "1": [ @@ -15,14 +15,14 @@ { "id": "test" }, - "test.spanning.bam:md5,47da98a17e3bc7b4b234c59a435a38ca" + "test.spanning.bam:md5,e80e6ce51627de3f3662201b0f0d3326" ] ], "2": [ [ "TRGT_GENOTYPE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ], "bam": [ @@ -30,7 +30,7 @@ { "id": "test" }, - "test.spanning.bam:md5,47da98a17e3bc7b4b234c59a435a38ca" + "test.spanning.bam:md5,e80e6ce51627de3f3662201b0f0d3326" ] ], "vcf": [ @@ -38,14 +38,14 @@ { "id": "test" }, - "test.vcf.gz:md5,cb694061956ddcd63772baf9a0720624" + "test.vcf.gz:md5,791ad621617ff0e7eab5892404d17592" ] ], "versions_trgt": [ [ "TRGT_GENOTYPE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ] } @@ -54,7 +54,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-09T16:16:00.489435938" + "timestamp": "2025-12-10T13:38:44.264999205" }, "homo sapiens - [bam,bai,[]], [fa,fai], bed - stub": { "content": [ @@ -64,7 +64,7 @@ { "id": "test" }, - "test.vcf.gz:md5,2015f1ef3d10bf8ce99882099b61b185" + "test.vcf.gz:md5,cb341e663ae5dfa7059a645335107268" ] ], "1": [ @@ -72,14 +72,14 @@ { "id": "test" }, - "test.spanning.bam:md5,1370db3a5d025cdde50676fab4235c5f" + "test.spanning.bam:md5,0a0a29eabbc7272a9e81d286da1330e8" ] ], "2": [ [ "TRGT_GENOTYPE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ], "bam": [ @@ -87,7 +87,7 @@ { "id": "test" }, - "test.spanning.bam:md5,1370db3a5d025cdde50676fab4235c5f" + "test.spanning.bam:md5,0a0a29eabbc7272a9e81d286da1330e8" ] ], "vcf": [ @@ -95,14 +95,14 @@ { "id": "test" }, - "test.vcf.gz:md5,2015f1ef3d10bf8ce99882099b61b185" + "test.vcf.gz:md5,cb341e663ae5dfa7059a645335107268" ] ], "versions_trgt": [ [ "TRGT_GENOTYPE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ] } @@ -111,7 +111,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-09T16:16:15.759484541" + "timestamp": "2025-12-10T13:38:58.276196691" }, "homo sapiens - [bam,bai,XX], [fa,fai], bed - stub": { "content": [ @@ -136,7 +136,7 @@ [ "TRGT_GENOTYPE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ], "bam": [ @@ -159,7 +159,7 @@ [ "TRGT_GENOTYPE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ] } @@ -168,7 +168,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-09T16:16:10.709433028" + "timestamp": "2025-12-10T13:38:53.536915603" }, "homo sapiens - [bam,bai,[]], [fa,fai], bed": { "content": [ @@ -178,7 +178,7 @@ { "id": "test" }, - "test.vcf.gz:md5,2015f1ef3d10bf8ce99882099b61b185" + "test.vcf.gz:md5,cb341e663ae5dfa7059a645335107268" ] ], "1": [ @@ -186,14 +186,14 @@ { "id": "test" }, - "test.spanning.bam:md5,1370db3a5d025cdde50676fab4235c5f" + "test.spanning.bam:md5,0a0a29eabbc7272a9e81d286da1330e8" ] ], "2": [ [ "TRGT_GENOTYPE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ], "bam": [ @@ -201,7 +201,7 @@ { "id": "test" }, - "test.spanning.bam:md5,1370db3a5d025cdde50676fab4235c5f" + "test.spanning.bam:md5,0a0a29eabbc7272a9e81d286da1330e8" ] ], "vcf": [ @@ -209,14 +209,14 @@ { "id": "test" }, - "test.vcf.gz:md5,2015f1ef3d10bf8ce99882099b61b185" + "test.vcf.gz:md5,cb341e663ae5dfa7059a645335107268" ] ], "versions_trgt": [ [ "TRGT_GENOTYPE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ] } @@ -225,6 +225,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-09T16:16:05.648952742" + "timestamp": "2025-12-10T13:38:49.040404319" } } \ No newline at end of file diff --git a/modules/nf-core/trgt/merge/environment.yml b/modules/nf-core/trgt/merge/environment.yml index 5ff336d40646..3a5bdd3bf721 100644 --- a/modules/nf-core/trgt/merge/environment.yml +++ b/modules/nf-core/trgt/merge/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::trgt=4.1.0 + - bioconda::trgt=5.0.0 diff --git a/modules/nf-core/trgt/merge/main.nf b/modules/nf-core/trgt/merge/main.nf index 07cf2d9c640f..24c4d59a13ba 100644 --- a/modules/nf-core/trgt/merge/main.nf +++ b/modules/nf-core/trgt/merge/main.nf @@ -4,8 +4,8 @@ process TRGT_MERGE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/trgt:4.1.0--h9ee0642_0': - 'biocontainers/trgt:4.1.0--h9ee0642_0' }" + 'https://depot.galaxyproject.org/singularity/trgt:5.0.0--h9ee0642_0': + 'biocontainers/trgt:5.0.0--h9ee0642_0' }" input: tuple val(meta) , path(vcfs), path(tbis) diff --git a/modules/nf-core/trgt/merge/tests/main.nf.test.snap b/modules/nf-core/trgt/merge/tests/main.nf.test.snap index 147860e39619..4168ceba4ce0 100644 --- a/modules/nf-core/trgt/merge/tests/main.nf.test.snap +++ b/modules/nf-core/trgt/merge/tests/main.nf.test.snap @@ -1,7 +1,7 @@ { "homo sapiens - 2 VCFs - reference": { "content": [ - "ec69cbc40d4a9766d87a62ba4835ae52", + "497b2c70fe41ad0c67c5fc4e1f281227", "VcfFile [chromosomes=[chr22], sampleCount=2, variantCount=1, phased=false, phasedAutodetect=false]", 2, { @@ -9,7 +9,7 @@ [ "TRGT_MERGE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ] } @@ -18,11 +18,11 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-06T13:08:24.392230593" + "timestamp": "2025-12-10T13:39:09.705242328" }, "homo sapiens - 2 VCFs": { "content": [ - "ec69cbc40d4a9766d87a62ba4835ae52", + "497b2c70fe41ad0c67c5fc4e1f281227", "VcfFile [chromosomes=[chr22], sampleCount=2, variantCount=1, phased=false, phasedAutodetect=false]", 2, { @@ -30,7 +30,7 @@ [ "TRGT_MERGE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ] } @@ -39,7 +39,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-06T13:08:18.192678929" + "timestamp": "2025-12-10T13:39:03.993142872" }, "homo sapiens - 2 VCFs - stub": { "content": [ @@ -56,7 +56,7 @@ [ "TRGT_MERGE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ], "vcf": [ @@ -71,7 +71,7 @@ [ "TRGT_MERGE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ] }, @@ -80,7 +80,7 @@ [ "TRGT_MERGE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ] } @@ -89,11 +89,11 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-06T13:08:42.242325427" + "timestamp": "2025-12-10T13:39:26.797540928" }, "homo sapiens - 1 VCF - --force-single": { "content": [ - "57131f453c695cbea40812f6c246d0f", + "bad30e1ef353973510fcf4125d127a13", "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=1, phased=false, phasedAutodetect=false]", 1, { @@ -101,7 +101,7 @@ [ "TRGT_MERGE", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ] } @@ -110,6 +110,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-06T13:08:36.269439614" + "timestamp": "2025-12-10T13:39:21.394392963" } } \ No newline at end of file diff --git a/modules/nf-core/trgt/plot/environment.yml b/modules/nf-core/trgt/plot/environment.yml index 5ff336d40646..3a5bdd3bf721 100644 --- a/modules/nf-core/trgt/plot/environment.yml +++ b/modules/nf-core/trgt/plot/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::trgt=4.1.0 + - bioconda::trgt=5.0.0 diff --git a/modules/nf-core/trgt/plot/main.nf b/modules/nf-core/trgt/plot/main.nf index c0d70507e2e9..a66b4459b6ea 100644 --- a/modules/nf-core/trgt/plot/main.nf +++ b/modules/nf-core/trgt/plot/main.nf @@ -4,8 +4,8 @@ process TRGT_PLOT { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/trgt:4.1.0--h9ee0642_0': - 'biocontainers/trgt:4.1.0--h9ee0642_0' }" + 'https://depot.galaxyproject.org/singularity/trgt:5.0.0--h9ee0642_0': + 'biocontainers/trgt:5.0.0--h9ee0642_0' }" input: tuple val(meta) , path(bam), path(bai), path(vcf), path(tbi), val(repeat_id) diff --git a/modules/nf-core/trgt/plot/tests/main.nf.test.snap b/modules/nf-core/trgt/plot/tests/main.nf.test.snap index 4590da7275fb..cb98204b8927 100644 --- a/modules/nf-core/trgt/plot/tests/main.nf.test.snap +++ b/modules/nf-core/trgt/plot/tests/main.nf.test.snap @@ -7,7 +7,7 @@ [ "TRGT_PLOT", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ] } @@ -16,7 +16,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-06T13:08:55.463192387" + "timestamp": "2025-12-10T13:39:38.423667557" }, "homo sapiens - [bam, bai, vcf, TEST], fasta, fai, bed": { "content": [ @@ -26,7 +26,7 @@ [ "TRGT_PLOT", "trgt", - "4.1.0-39fa24c" + "5.0.0-e9acee0" ] ] } @@ -35,6 +35,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-06T13:08:48.783944144" + "timestamp": "2025-12-10T13:39:32.505468731" } } \ No newline at end of file From a939428f25e39d5b4197eb246ecfaf62bac4c1ef Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> Date: Wed, 10 Dec 2025 14:28:50 +0100 Subject: [PATCH 50/83] Channel -> channel in some subwfs (#9542) Channel -> channel --- .../nf-core/utils_nfcore_pipeline/main.nf | 2 +- .../vcf_annotate_ensemblvep_snpeff/main.nf | 20 +++++++++---------- .../nf-core/vcf_annotate_snpeff/main.nf | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf index bfd258760d2b..2f30e9a4632a 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf @@ -98,7 +98,7 @@ def workflowVersionToYAML() { // Get channel of software versions used in pipeline in YAML format // def softwareVersionsToYAML(ch_versions) { - return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(Channel.of(workflowVersionToYAML())) + return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(channel.of(workflowVersionToYAML())) } // diff --git a/subworkflows/nf-core/vcf_annotate_ensemblvep_snpeff/main.nf b/subworkflows/nf-core/vcf_annotate_ensemblvep_snpeff/main.nf index a2e49ec69f54..95557a791930 100644 --- a/subworkflows/nf-core/vcf_annotate_ensemblvep_snpeff/main.nf +++ b/subworkflows/nf-core/vcf_annotate_ensemblvep_snpeff/main.nf @@ -25,9 +25,9 @@ workflow VCF_ANNOTATE_ENSEMBLVEP_SNPEFF { val_sites_per_chunk // value: the amount of variants per scattered VCF main: - def ch_versions = Channel.empty() - def ch_vep_input = Channel.empty() - def ch_scatter = Channel.empty() + def ch_versions = channel.empty() + def ch_vep_input = channel.empty() + def ch_scatter = channel.empty() // Check if val_sites_per_chunk is set and scatter if it is if(val_sites_per_chunk) { @@ -89,8 +89,8 @@ workflow VCF_ANNOTATE_ENSEMBLVEP_SNPEFF { } // Annotate with ensemblvep if it's part of the requested tools - def ch_vep_output = Channel.empty() - def ch_vep_reports = Channel.empty() + def ch_vep_output = channel.empty() + def ch_vep_reports = channel.empty() if("ensemblvep" in val_tools_to_use){ ENSEMBLVEP_VEP( ch_vep_input, @@ -110,10 +110,10 @@ workflow VCF_ANNOTATE_ENSEMBLVEP_SNPEFF { } // Annotate with snpeff if it's part of the requested tools - def ch_snpeff_output = Channel.empty() - def ch_snpeff_reports = Channel.empty() - def ch_snpeff_html = Channel.empty() - def ch_snpeff_genes = Channel.empty() + def ch_snpeff_output = channel.empty() + def ch_snpeff_reports = channel.empty() + def ch_snpeff_html = channel.empty() + def ch_snpeff_genes = channel.empty() if("snpeff" in val_tools_to_use){ SNPEFF_SNPEFF( ch_vep_output, @@ -137,7 +137,7 @@ workflow VCF_ANNOTATE_ENSEMBLVEP_SNPEFF { } // Gather the files back together if they were scattered - def ch_ready_vcfs = Channel.empty() + def ch_ready_vcfs = channel.empty() if(val_sites_per_chunk) { // // Concatenate the VCFs back together with bcftools concat diff --git a/subworkflows/nf-core/vcf_annotate_snpeff/main.nf b/subworkflows/nf-core/vcf_annotate_snpeff/main.nf index 5958b15b669f..a9fd98640578 100644 --- a/subworkflows/nf-core/vcf_annotate_snpeff/main.nf +++ b/subworkflows/nf-core/vcf_annotate_snpeff/main.nf @@ -12,7 +12,7 @@ workflow VCF_ANNOTATE_SNPEFF { ch_snpeff_cache // channel: [ path(cache) ] (optional) main: - ch_versions = Channel.empty() + ch_versions = channel.empty() SNPEFF_SNPEFF(ch_vcf, val_snpeff_db, ch_snpeff_cache) TABIX_BGZIPTABIX(SNPEFF_SNPEFF.out.vcf) From 9d6f62888f65365af9f44d2f42e6c4256bd651a1 Mon Sep 17 00:00:00 2001 From: Adrien Coulier Date: Wed, 10 Dec 2025 14:55:31 +0100 Subject: [PATCH 51/83] Migrate cat/fastq to topic channel (#9543) * Migrate cat/fastq to topic channel * Remove out.versions in related subworkflows * Update snapshots (again) --- modules/nf-core/cat/fastq/main.nf | 22 +- modules/nf-core/cat/fastq/meta.yml | 28 ++- .../nf-core/cat/fastq/tests/main.nf.test.snap | 200 ++++++++++++------ .../main.nf | 2 - 4 files changed, 163 insertions(+), 89 deletions(-) diff --git a/modules/nf-core/cat/fastq/main.nf b/modules/nf-core/cat/fastq/main.nf index acfb6d0e6221..8480e383f9f5 100644 --- a/modules/nf-core/cat/fastq/main.nf +++ b/modules/nf-core/cat/fastq/main.nf @@ -12,7 +12,7 @@ process CAT_FASTQ { output: tuple val(meta), path("*.merged.fastq.gz"), emit: reads - path "versions.yml", emit: versions + tuple val("${task.process}"), val("cat"), eval("cat --version 2>&1 | head -n 1 | sed 's/^.*coreutils) //; s/ .*\$//'"), emit: versions_cat, topic: versions when: task.ext.when == null || task.ext.when @@ -24,11 +24,6 @@ process CAT_FASTQ { if (readList.size >= 1) { """ cat ${readList.join(' ')} > ${prefix}.merged.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') - END_VERSIONS """ } else { error("Could not find any FASTQ files to concatenate in the process input") @@ -42,11 +37,6 @@ process CAT_FASTQ { """ cat ${read1.join(' ')} > ${prefix}_1.merged.fastq.gz cat ${read2.join(' ')} > ${prefix}_2.merged.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') - END_VERSIONS """ } else { error("Could not find any FASTQ file pairs to concatenate in the process input") @@ -60,11 +50,6 @@ process CAT_FASTQ { if (readList.size >= 1) { """ echo '' | gzip > ${prefix}.merged.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') - END_VERSIONS """ } else { error("Could not find any FASTQ files to concatenate in the process input") @@ -75,11 +60,6 @@ process CAT_FASTQ { """ echo '' | gzip > ${prefix}_1.merged.fastq.gz echo '' | gzip > ${prefix}_2.merged.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') - END_VERSIONS """ } else { error("Could not find any FASTQ file pairs to concatenate in the process input") diff --git a/modules/nf-core/cat/fastq/meta.yml b/modules/nf-core/cat/fastq/meta.yml index 40d2f627cec0..8fc03bdc2d14 100644 --- a/modules/nf-core/cat/fastq/meta.yml +++ b/modules/nf-core/cat/fastq/meta.yml @@ -34,13 +34,29 @@ output: description: Merged fastq file pattern: "*.{merged.fastq.gz}" ontologies: [] + versions_cat: + - - ${task.process}: + type: string + description: The process the versions were collected from + - cat: + type: string + description: The tool name + - cat --version 2>&1 | head -n 1 | sed 's/^.*coreutils) //; s/ .*\$//': + type: eval + description: The expression to obtain the version of the tool + +topics: versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - - ${task.process}: + type: string + description: The process the versions were collected from + - cat: + type: string + description: The tool name + - cat --version 2>&1 | head -n 1 | sed 's/^.*coreutils) //; s/ .*\$//': + type: eval + description: The expression to obtain the version of the tool + authors: - "@joseespinosa" - "@drpatelh" diff --git a/modules/nf-core/cat/fastq/tests/main.nf.test.snap b/modules/nf-core/cat/fastq/tests/main.nf.test.snap index ee5ab364763f..e2a94249799d 100644 --- a/modules/nf-core/cat/fastq/tests/main.nf.test.snap +++ b/modules/nf-core/cat/fastq/tests/main.nf.test.snap @@ -22,7 +22,11 @@ ] ], "1": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ], "reads": [ [ @@ -33,16 +37,20 @@ "test.merged.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec" ] ], - "versions": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-02-25T17:24:04.902821069" + "timestamp": "2025-12-10T14:31:42.84401526" }, "test_cat_fastq_paired_end_same_name": { "content": [ @@ -60,7 +68,11 @@ ] ], "1": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ], "reads": [ [ @@ -74,16 +86,20 @@ ] ] ], - "versions": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-02-25T17:23:57.476357974" + "timestamp": "2025-12-10T14:31:36.820489323" }, "test_cat_fastq_paired_end_same_name - stub": { "content": [ @@ -101,7 +117,11 @@ ] ], "1": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ], "reads": [ [ @@ -115,16 +135,20 @@ ] ] ], - "versions": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-02-25T17:24:34.615815265" + "timestamp": "2025-12-10T14:32:06.262192935" }, "test_cat_fastq_single_end": { "content": [ @@ -139,7 +163,11 @@ ] ], "1": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ], "reads": [ [ @@ -150,16 +178,20 @@ "test.merged.fastq.gz:md5,ee314a9bd568d06617171b0c85f508da" ] ], - "versions": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-02-25T17:23:32.489874386" + "timestamp": "2025-12-10T14:31:18.859169785" }, "test_cat_fastq_single_end_same_name": { "content": [ @@ -174,7 +206,11 @@ ] ], "1": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ], "reads": [ [ @@ -185,16 +221,20 @@ "test.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22" ] ], - "versions": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-02-25T17:23:49.184759506" + "timestamp": "2025-12-10T14:31:30.942615287" }, "test_cat_fastq_single_end - stub": { "content": [ @@ -209,7 +249,11 @@ ] ], "1": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ], "reads": [ [ @@ -220,16 +264,20 @@ "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-02-25T17:24:12.857293744" + "timestamp": "2025-12-10T14:31:48.827990633" }, "test_cat_fastq_paired_end_no_files": { "content": [ @@ -264,7 +312,11 @@ ] ], "1": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ], "reads": [ [ @@ -275,16 +327,20 @@ "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-02-25T17:24:27.816080065" + "timestamp": "2025-12-10T14:32:00.586584379" }, "test_cat_fastq_paired_end": { "content": [ @@ -302,7 +358,11 @@ ] ], "1": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ], "reads": [ [ @@ -316,16 +376,20 @@ ] ] ], - "versions": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-02-25T17:23:41.739469187" + "timestamp": "2025-12-10T14:31:25.159365603" }, "test_cat_fastq_single_end_no_files": { "content": [ @@ -353,7 +417,11 @@ ] ], "1": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ], "reads": [ [ @@ -367,16 +435,20 @@ ] ] ], - "versions": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-02-25T17:24:21.178950408" + "timestamp": "2025-12-10T14:31:54.850702874" }, "test_cat_fastq_single_end_single_file - stub": { "content": [ @@ -391,7 +463,11 @@ ] ], "1": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ], "reads": [ [ @@ -402,15 +478,19 @@ "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + "versions_cat": [ + [ + "CAT_FASTQ", + "cat", + "9.5" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-02-25T17:24:40.851404993" + "timestamp": "2025-12-10T14:32:11.746498148" } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/main.nf b/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/main.nf index db839531b7cc..84a029b30754 100644 --- a/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/main.nf +++ b/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/main.nf @@ -148,8 +148,6 @@ workflow FASTQ_QC_TRIM_FILTER_SETSTRANDEDNESS { ch_fastq.multiple ).reads.mix(ch_fastq.single).set { ch_filtered_reads } - ch_versions = ch_versions.mix(CAT_FASTQ.out.versions.first()) - // // MODULE: Lint FastQ files // From 7a6165fa3e72ea86f12d70542f594a7e099ea062 Mon Sep 17 00:00:00 2001 From: Georgia Kesisoglou Date: Wed, 10 Dec 2025 15:12:33 +0100 Subject: [PATCH 52/83] Add module picard/collectvariantcallingmetrics (#9502) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add module picard/collectvariantcallingmetrics * Run prettier * Fix format * Make one input tuple * Change test input structure * Add md5 checksum * Update snapshot * Update meta.yml * Support multithreading * Remove TODO Co-authored-by: Famke Bäuerle <45968370+famosab@users.noreply.github.com> --------- Co-authored-by: Famke Bäuerle <45968370+famosab@users.noreply.github.com> --- .../environment.yml | 7 + .../collectvariantcallingmetrics/main.nf | 64 +++++++++ .../collectvariantcallingmetrics/meta.yml | 88 ++++++++++++ .../tests/main.nf.test | 130 ++++++++++++++++++ .../tests/main.nf.test.snap | 128 +++++++++++++++++ 5 files changed, 417 insertions(+) create mode 100644 modules/nf-core/picard/collectvariantcallingmetrics/environment.yml create mode 100644 modules/nf-core/picard/collectvariantcallingmetrics/main.nf create mode 100644 modules/nf-core/picard/collectvariantcallingmetrics/meta.yml create mode 100644 modules/nf-core/picard/collectvariantcallingmetrics/tests/main.nf.test create mode 100644 modules/nf-core/picard/collectvariantcallingmetrics/tests/main.nf.test.snap diff --git a/modules/nf-core/picard/collectvariantcallingmetrics/environment.yml b/modules/nf-core/picard/collectvariantcallingmetrics/environment.yml new file mode 100644 index 000000000000..7b0de0faaf1e --- /dev/null +++ b/modules/nf-core/picard/collectvariantcallingmetrics/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::picard=3.4.0" diff --git a/modules/nf-core/picard/collectvariantcallingmetrics/main.nf b/modules/nf-core/picard/collectvariantcallingmetrics/main.nf new file mode 100644 index 000000000000..a4d575400ca8 --- /dev/null +++ b/modules/nf-core/picard/collectvariantcallingmetrics/main.nf @@ -0,0 +1,64 @@ +process PICARD_COLLECTVARIANTCALLINGMETRICS { + tag "${meta.id}" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/picard:3.4.0--hdfd78af_0' + : 'biocontainers/picard:3.4.0--hdfd78af_0'}" + + input: + tuple val(meta), path(vcf), path(index), path(intervals_file), path(fasta), path(dict), path(dbsnp), path(dbsnp_index) + + output: + tuple val(meta), path("*.variant_calling_detail_metrics"), emit: detail_metrics + tuple val(meta), path("*.variant_calling_summary_metrics"), emit: summary_metrics + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" + def intervals = intervals_file ? "--TARGET_INTERVALS ${intervals_file}" : "" + + def avail_mem = 3072 + if (!task.memory) { + log.info('[Picard CollectVariantCallingMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() + } + """ + picard \\ + -Xmx${avail_mem}M \\ + CollectVariantCallingMetrics \\ + ${args} \\ + --THREAD_COUNT ${task.cpus} \\ + --INPUT ${vcf} \\ + --OUTPUT ${prefix} \\ + --DBSNP ${dbsnp} \\ + ${reference} \\ + --TMP_DIR . \\ + ${intervals} \\ + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + picard: \$(echo \$(picard CollectVariantCallingMetrics --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.variant_calling_detail_metrics + touch ${prefix}.variant_calling_summary_metrics + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + picard: \$(echo \$(picard CollectVariantCallingMetrics --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) + END_VERSIONS + """ +} diff --git a/modules/nf-core/picard/collectvariantcallingmetrics/meta.yml b/modules/nf-core/picard/collectvariantcallingmetrics/meta.yml new file mode 100644 index 000000000000..8ed1aa6b2c1a --- /dev/null +++ b/modules/nf-core/picard/collectvariantcallingmetrics/meta.yml @@ -0,0 +1,88 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "picard_collectvariantcallingmetrics" +description: Collects per-sample and aggregate (spanning all samples) metrics from the provided VCF file +keywords: + - vcf + - metrics + - variant calling + - statistics +tools: + - "picard": + description: "A set of command line tools (in Java) for manipulating high-throughput sequencing (HTS) data and formats such as SAM/BAM/CRAM and VCF." + homepage: "https://broadinstitute.github.io/picard/" + documentation: "https://broadinstitute.github.io/picard/" + tool_dev_url: "https://github.com/broadinstitute/picard" + licence: ["MIT"] + identifier: biotools:picard_tools + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - vcf: + type: file + description: Input VCF file for analysis + pattern: "*.{vcf,vcf.gz}" + ontologies: + - edam: "http://edamontology.org/format_3016" # VCF + - index: + type: file + description: Index file for the input VCF file + pattern: "*.{idx,tbi}" + - intervals_file: + type: file + description: Optional BED file specifying target intervals + pattern: "*.{bed,bed.gz,intervals_list}" + - fasta: + type: file + description: Reference sequence file + pattern: "*.{fasta,fa,fasta.gz,fa.gz}" + ontologies: + - edam: "http://edamontology.org/format_1929" # FASTA + - dict: + type: file + description: Reference sequence dictionary file + pattern: "*.{dict}" + - dbsnp: + type: file + description: Reference dbSNP file in dbSNP or VCF format + pattern: "*.{vcf,vcf.gz}" + ontologies: + - edam: "http://edamontology.org/format_3016" # VCF + - dbsnp_index: + type: file + description: Reference dbSNP file in dbSNP or VCF format + pattern: "*.{idx,tbi}" +output: + detail_metrics: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.variant_calling_detail_metrics": + type: file + description: Detailed variant calling metrics file + pattern: "*.variant_calling_detail_metrics" + summary_metrics: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.variant_calling_summary_metrics": + type: file + description: Summary variant calling metrics file + pattern: "*.variant_calling_summary_metrics" + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + +authors: + - "@georgiakes" +maintainers: + - "@georgiakes" diff --git a/modules/nf-core/picard/collectvariantcallingmetrics/tests/main.nf.test b/modules/nf-core/picard/collectvariantcallingmetrics/tests/main.nf.test new file mode 100644 index 000000000000..3170f70d908a --- /dev/null +++ b/modules/nf-core/picard/collectvariantcallingmetrics/tests/main.nf.test @@ -0,0 +1,130 @@ +nextflow_process { + + name "Test Process PICARD_COLLECTVARIANTCALLINGMETRICS" + script "../main.nf" + process "PICARD_COLLECTVARIANTCALLINGMETRICS" + + tag "modules" + tag "modules_nfcore" + tag "picard" + tag "picard/collectvariantcallingmetrics" + + test("homo_sapiens - vcf_gz") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), + [], + 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.dict', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/dbsnp_146.hg38.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/dbsnp_146.hg38.vcf.gz.tbi', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.detail_metrics[0][1]).readLines()[5..7].join('\n').md5(), + path(process.out.summary_metrics[0][1]).readLines()[5..7].join('\n').md5(), + process.out.versions + ).match() } + ) + } + } + + test("homo_sapiens - vcf_gz - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), + [], + 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.dict', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/dbsnp_146.hg38.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/dbsnp_146.hg38.vcf.gz.tbi', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + test("homo_sapiens - vcf_gz - intervals"){ + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.interval_list',checkIfExists: true), + 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.dict', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/dbsnp_146.hg38.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/dbsnp_146.hg38.vcf.gz.tbi', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.detail_metrics[0][1]).readLines()[5..7].join('\n').md5(), + path(process.out.summary_metrics[0][1]).readLines()[5..7].join('\n').md5(), + process.out.versions + ).match() } + ) + } + } + + test("homo_sapiens - vcf_gz - intervals - stub"){ + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gvcf/test.genome.vcf.gz.tbi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.interval_list', checkIfExists: true ), + 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.dict', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/dbsnp_146.hg38.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/dbsnp_146.hg38.vcf.gz.tbi', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/picard/collectvariantcallingmetrics/tests/main.nf.test.snap b/modules/nf-core/picard/collectvariantcallingmetrics/tests/main.nf.test.snap new file mode 100644 index 000000000000..1f52f4f01468 --- /dev/null +++ b/modules/nf-core/picard/collectvariantcallingmetrics/tests/main.nf.test.snap @@ -0,0 +1,128 @@ +{ + "homo_sapiens - vcf_gz - intervals": { + "content": [ + "5e8fa4113bb01326f02cc7141f7f4a34", + "89a2e0f50710f9731454826fe5773eb3", + [ + "versions.yml:md5,39c73fe733d00495f4c9dcf246dc9842" + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.8" + }, + "timestamp": "2025-12-09T14:09:36.731526746" + }, + "homo_sapiens - vcf_gz - intervals - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.variant_calling_detail_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.variant_calling_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,39c73fe733d00495f4c9dcf246dc9842" + ], + "detail_metrics": [ + [ + { + "id": "test" + }, + "test.variant_calling_detail_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "summary_metrics": [ + [ + { + "id": "test" + }, + "test.variant_calling_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,39c73fe733d00495f4c9dcf246dc9842" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.8" + }, + "timestamp": "2025-12-03T18:25:29.532942217" + }, + "homo_sapiens - vcf_gz - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.variant_calling_detail_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.variant_calling_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,39c73fe733d00495f4c9dcf246dc9842" + ], + "detail_metrics": [ + [ + { + "id": "test" + }, + "test.variant_calling_detail_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "summary_metrics": [ + [ + { + "id": "test" + }, + "test.variant_calling_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,39c73fe733d00495f4c9dcf246dc9842" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.8" + }, + "timestamp": "2025-12-03T18:25:01.898211511" + }, + "homo_sapiens - vcf_gz": { + "content": [ + "f7ea8a1edb9f4b9eb971689d4cb375f6", + "2f378ee24e3c23f170296b4b67cda2a4", + [ + "versions.yml:md5,39c73fe733d00495f4c9dcf246dc9842" + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.8" + }, + "timestamp": "2025-12-09T14:09:12.975803164" + } +} \ No newline at end of file From 24b5c0c7463fe4fc4c63c47f2c2548e4744678aa Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> Date: Wed, 10 Dec 2025 15:25:52 +0100 Subject: [PATCH 53/83] fix tabix/tabix stub (#9544) * fix tabix stub * bump max shards to 16 --- .github/workflows/nf-test.yml | 2 +- modules/nf-core/tabix/tabix/main.nf | 3 +-- .../nf-core/tabix/tabix/tests/main.nf.test.snap | 16 +++++----------- .../tests/main.nf.test.snap | 16 +++++----------- .../vcf_gather_bcftools/tests/main.nf.test.snap | 16 +++++----------- 5 files changed, 17 insertions(+), 36 deletions(-) diff --git a/.github/workflows/nf-test.yml b/.github/workflows/nf-test.yml index b416b59ef959..ef39ca436861 100644 --- a/.github/workflows/nf-test.yml +++ b/.github/workflows/nf-test.yml @@ -77,7 +77,7 @@ jobs: env: NFT_VER: ${{ env.NFT_VER }} with: - max_shards: 15 + max_shards: 16 paths: "${{ join(fromJson(steps.list.outputs.components ), ' ') }}" - name: debug diff --git a/modules/nf-core/tabix/tabix/main.nf b/modules/nf-core/tabix/tabix/main.nf index 602a82a16d38..c8bcef64eeef 100644 --- a/modules/nf-core/tabix/tabix/main.nf +++ b/modules/nf-core/tabix/tabix/main.nf @@ -30,7 +30,6 @@ process TABIX_TABIX { def args = task.ext.args ?: '' def index = args.contains("-C ") || args.contains("--csi") ? "csi" : "tbi" """ - touch ${tab}.tbi - touch ${tab}.csi + touch ${tab}.${index} """ } diff --git a/modules/nf-core/tabix/tabix/tests/main.nf.test.snap b/modules/nf-core/tabix/tabix/tests/main.nf.test.snap index 7e4c1ee76a42..91a3a66de0e4 100644 --- a/modules/nf-core/tabix/tabix/tests/main.nf.test.snap +++ b/modules/nf-core/tabix/tabix/tests/main.nf.test.snap @@ -130,10 +130,7 @@ { "id": "vcf_csi_stub" }, - [ - "test.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "test.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "1": [ @@ -148,10 +145,7 @@ { "id": "vcf_csi_stub" }, - [ - "test.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "test.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "versions_tabix": [ @@ -164,10 +158,10 @@ } ], "meta": { - "nf-test": "0.9.3", - "nextflow": "25.04.7" + "nf-test": "0.9.2", + "nextflow": "25.10.2" }, - "timestamp": "2025-11-20T13:47:46.12436" + "timestamp": "2025-12-10T14:31:29.90297082" }, "sarscov2_vcf_csi": { "content": [ diff --git a/subworkflows/nf-core/vcf_annotate_ensemblvep/tests/main.nf.test.snap b/subworkflows/nf-core/vcf_annotate_ensemblvep/tests/main.nf.test.snap index a0eb0a8a9a59..6eaa0601a081 100644 --- a/subworkflows/nf-core/vcf_annotate_ensemblvep/tests/main.nf.test.snap +++ b/subworkflows/nf-core/vcf_annotate_ensemblvep/tests/main.nf.test.snap @@ -32,10 +32,7 @@ "id": "test" }, "test.vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - [ - "test.vep.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "test.vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "1": [ @@ -65,10 +62,7 @@ "id": "test" }, "test.vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - [ - "test.vep.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "test.vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "versions": [ @@ -77,9 +71,9 @@ } ], "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nf-test": "0.9.2", + "nextflow": "25.10.2" }, - "timestamp": "2025-11-28T09:51:42.245769" + "timestamp": "2025-12-10T14:35:25.633650675" } } \ No newline at end of file diff --git a/subworkflows/nf-core/vcf_gather_bcftools/tests/main.nf.test.snap b/subworkflows/nf-core/vcf_gather_bcftools/tests/main.nf.test.snap index 6619008d9fb2..a106f79c0e58 100644 --- a/subworkflows/nf-core/vcf_gather_bcftools/tests/main.nf.test.snap +++ b/subworkflows/nf-core/vcf_gather_bcftools/tests/main.nf.test.snap @@ -53,10 +53,7 @@ { "id": "test" }, - [ - "test.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "2": [ @@ -68,10 +65,7 @@ { "id": "test" }, - [ - "test.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "vcf": [ @@ -101,9 +95,9 @@ ] ], "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nf-test": "0.9.2", + "nextflow": "25.10.2" }, - "timestamp": "2025-11-27T16:36:39.797305" + "timestamp": "2025-12-10T14:41:23.392663555" } } \ No newline at end of file From f13b9a9e1d8164d825414afc1d1dc69998f41083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Mir=20Pedrol?= Date: Wed, 10 Dec 2025 16:05:41 +0100 Subject: [PATCH 54/83] Unify msa modules (#9539) * add mafft_align subworkflow to prepare channels for mafft/align like all other msa modules * default output format fasta for tcoffee align and regressive to match other msa modules * [automated] Fix linting with Prettier * Update subworkflows/nf-core/mafft_align/main.nf Co-authored-by: Jose Espinosa-Carrasco --------- Co-authored-by: nf-core-bot Co-authored-by: Jose Espinosa-Carrasco --- modules/nf-core/tcoffee/align/main.nf | 14 +++-- .../nf-core/tcoffee/align/tests/lib.config | 2 +- .../nf-core/tcoffee/align/tests/main.nf.test | 7 --- .../tcoffee/align/tests/sequence.config | 3 - .../nf-core/tcoffee/align/tests/tree.config | 5 -- modules/nf-core/tcoffee/regressive/main.nf | 12 ++-- .../tcoffee/regressive/tests/main.nf.test | 7 --- .../tcoffee/regressive/tests/sequence.config | 3 - .../tcoffee/regressive/tests/tree.config | 5 -- modules/nf-core/tcoffee/tcs/tests/lib.config | 2 +- subworkflows/nf-core/mafft_align/main.nf | 15 +++++ subworkflows/nf-core/mafft_align/meta.yml | 60 +++++++++++++++++++ .../nf-core/mafft_align/tests/main.nf.test | 36 +++++++++++ .../mafft_align/tests/main.nf.test.snap | 39 ++++++++++++ 14 files changed, 167 insertions(+), 43 deletions(-) delete mode 100644 modules/nf-core/tcoffee/align/tests/sequence.config delete mode 100644 modules/nf-core/tcoffee/align/tests/tree.config delete mode 100644 modules/nf-core/tcoffee/regressive/tests/sequence.config delete mode 100644 modules/nf-core/tcoffee/regressive/tests/tree.config create mode 100644 subworkflows/nf-core/mafft_align/main.nf create mode 100644 subworkflows/nf-core/mafft_align/meta.yml create mode 100644 subworkflows/nf-core/mafft_align/tests/main.nf.test create mode 100644 subworkflows/nf-core/mafft_align/tests/main.nf.test.snap diff --git a/modules/nf-core/tcoffee/align/main.nf b/modules/nf-core/tcoffee/align/main.nf index e1f7d7f235bd..abdb79f0ee24 100644 --- a/modules/nf-core/tcoffee/align/main.nf +++ b/modules/nf-core/tcoffee/align/main.nf @@ -23,12 +23,13 @@ process TCOFFEE_ALIGN { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def tree_args = tree ? "-usetree $tree" : "" - def template_args = template ? "-template_file $template" : "" - def outfile = compress ? "stdout" : "${prefix}.aln" - def write_output = compress ? " | pigz -cp ${task.cpus} > ${prefix}.aln.gz" : "" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def tree_args = tree ? "-usetree $tree" : "" + def template_args = template ? "-template_file $template" : "" + def outfile = compress ? "stdout" : "${prefix}.aln" + def default_out_format = ("-output" in "${args}") ? "" : "-output fasta_aln" + def write_output = compress ? " | pigz -cp ${task.cpus} > ${prefix}.aln.gz" : "" """ export TEMP='./' export TMP_4_TCOFFEE="./" @@ -37,6 +38,7 @@ process TCOFFEE_ALIGN { $tree_args \ $template_args \ $args \ + $default_out_format \ -thread ${task.cpus} \ -outfile $outfile \ $write_output diff --git a/modules/nf-core/tcoffee/align/tests/lib.config b/modules/nf-core/tcoffee/align/tests/lib.config index 90e6181f56ef..98546f8492e5 100644 --- a/modules/nf-core/tcoffee/align/tests/lib.config +++ b/modules/nf-core/tcoffee/align/tests/lib.config @@ -1,3 +1,3 @@ process { - ext.args = { "-output fasta_aln -out_lib=sample_lib1.tc_lib" } + ext.args = { "-out_lib=sample_lib1.tc_lib" } } diff --git a/modules/nf-core/tcoffee/align/tests/main.nf.test b/modules/nf-core/tcoffee/align/tests/main.nf.test index 325a30469a9d..1b7914533c11 100644 --- a/modules/nf-core/tcoffee/align/tests/main.nf.test +++ b/modules/nf-core/tcoffee/align/tests/main.nf.test @@ -13,8 +13,6 @@ nextflow_process { test("align_sequence - compressed - seatoxin") { - config "./sequence.config" - when { process { """ @@ -39,8 +37,6 @@ nextflow_process { test("align_sequence - uncompressed - seatoxin") { - config "./sequence.config" - when { process { """ @@ -65,8 +61,6 @@ nextflow_process { test("align_with_guide_tree - uncompressed - seatoxin") { - config "./tree.config" - setup { run("FAMSA_GUIDETREE") { @@ -176,7 +170,6 @@ nextflow_process { test("align_sequence - uncompressed - seatoxin - stub") { options "-stub" - config "./sequence.config" when { process { diff --git a/modules/nf-core/tcoffee/align/tests/sequence.config b/modules/nf-core/tcoffee/align/tests/sequence.config deleted file mode 100644 index 69c6fc17c9c7..000000000000 --- a/modules/nf-core/tcoffee/align/tests/sequence.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = { "-output fasta_aln" } -} diff --git a/modules/nf-core/tcoffee/align/tests/tree.config b/modules/nf-core/tcoffee/align/tests/tree.config deleted file mode 100644 index d426ed454ab2..000000000000 --- a/modules/nf-core/tcoffee/align/tests/tree.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: "TCOFFEE_ALIGN"{ - ext.args = { "-output fasta_aln" } - } -} diff --git a/modules/nf-core/tcoffee/regressive/main.nf b/modules/nf-core/tcoffee/regressive/main.nf index 80206f473779..c247d2b4fde0 100644 --- a/modules/nf-core/tcoffee/regressive/main.nf +++ b/modules/nf-core/tcoffee/regressive/main.nf @@ -21,11 +21,12 @@ process TCOFFEE_REGRESSIVE { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def tree_args = tree ? "-reg_tree $tree" : "" - def template_args = template ? "-template_file $template" : "" - def outfile = compress ? "stdout" : "${prefix}.aln" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def tree_args = tree ? "-reg_tree $tree" : "" + def template_args = template ? "-template_file $template" : "" + def default_out_format = ("-output" in "${args}") ? "" : "-output fasta_aln" + def outfile = compress ? "stdout" : "${prefix}.aln" """ export TEMP='./' t_coffee -reg \ @@ -33,6 +34,7 @@ process TCOFFEE_REGRESSIVE { $tree_args \ $template_args \ $args \ + $default_out_format \ -reg_thread ${task.cpus} \ -outfile $outfile diff --git a/modules/nf-core/tcoffee/regressive/tests/main.nf.test b/modules/nf-core/tcoffee/regressive/tests/main.nf.test index 0d697b7304f6..b04dfa45ff39 100644 --- a/modules/nf-core/tcoffee/regressive/tests/main.nf.test +++ b/modules/nf-core/tcoffee/regressive/tests/main.nf.test @@ -13,8 +13,6 @@ nextflow_process { test("align_sequence - compressed - seatoxin") { - config "./sequence.config" - when { process { """ @@ -39,8 +37,6 @@ nextflow_process { test("align_sequence - uncompressed - seatoxin") { - config "./sequence.config" - when { process { """ @@ -65,8 +61,6 @@ nextflow_process { test("align_with_guide_tree - uncompressed - seatoxin") { - config "./tree.config" - setup { run("FAMSA_GUIDETREE") { @@ -107,7 +101,6 @@ nextflow_process { test("align_sequence - uncompressed - seatoxin - stub") { options "-stub" - config "./sequence.config" when { process { diff --git a/modules/nf-core/tcoffee/regressive/tests/sequence.config b/modules/nf-core/tcoffee/regressive/tests/sequence.config deleted file mode 100644 index 69c6fc17c9c7..000000000000 --- a/modules/nf-core/tcoffee/regressive/tests/sequence.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = { "-output fasta_aln" } -} diff --git a/modules/nf-core/tcoffee/regressive/tests/tree.config b/modules/nf-core/tcoffee/regressive/tests/tree.config deleted file mode 100644 index d426ed454ab2..000000000000 --- a/modules/nf-core/tcoffee/regressive/tests/tree.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: "TCOFFEE_ALIGN"{ - ext.args = { "-output fasta_aln" } - } -} diff --git a/modules/nf-core/tcoffee/tcs/tests/lib.config b/modules/nf-core/tcoffee/tcs/tests/lib.config index 610250ce2352..6d20715e72d9 100644 --- a/modules/nf-core/tcoffee/tcs/tests/lib.config +++ b/modules/nf-core/tcoffee/tcs/tests/lib.config @@ -1,7 +1,7 @@ process { withName: "TCOFFEE_ALIGN"{ - ext.args = { "-output fasta_aln -out_lib sample_lib1.tc_lib" } + ext.args = { "-out_lib sample_lib1.tc_lib" } } } diff --git a/subworkflows/nf-core/mafft_align/main.nf b/subworkflows/nf-core/mafft_align/main.nf new file mode 100644 index 000000000000..1b48e919c40d --- /dev/null +++ b/subworkflows/nf-core/mafft_align/main.nf @@ -0,0 +1,15 @@ +include { MAFFT_ALIGN as MAFFT_ALIGN_MODULE } from '../../../modules/nf-core/mafft/align/main' + +workflow MAFFT_ALIGN { + + take: + ch_fasta // channel: [ val(meta), fasta ] + + main: + + MAFFT_ALIGN_MODULE ( ch_fasta, [[], []], [[], []], [[], []], [[], []], [[], []], [] ) + + emit: + alignment = MAFFT_ALIGN_MODULE.out.fas // channel: [ val(meta), *.fas ] + versions = MAFFT_ALIGN_MODULE.out.versions // channel: [ versions.yml ] +} diff --git a/subworkflows/nf-core/mafft_align/meta.yml b/subworkflows/nf-core/mafft_align/meta.yml new file mode 100644 index 000000000000..aa62c14d5be0 --- /dev/null +++ b/subworkflows/nf-core/mafft_align/meta.yml @@ -0,0 +1,60 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "mafft_align" +description: Prepare channels for running MAFFT/align +keywords: + - msa + - mafft + - align +components: + - mafft/align +input: + - ch_fasta: + type: file + description: | + The input channel containing the FASTA files + pattern: "*.{bam/cram/sam}" + structure: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - fasta: + type: file + description: Input sequences in FASTA format + pattern: "*.{fa,fasta}" + ontologies: + - edam: http://edamontology.org/format_1929 +output: + - alignment: + type: file + description: Channel containing the alignment file in fasta format. + structure: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test']` + - "*.aln.gz": + type: file + description: Alignment file, in FASTA format. + pattern: "*.aln.gz" + ontologies: + - edam: http://edamontology.org/format_1984 + - versions: + type: file + description: Channel containing the software versions YAML file + structure: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML + +authors: + - "@mirpedrol" +maintainers: + - "@mirpedrol" + - "@luisas" + - "@JoseEspinosa" diff --git a/subworkflows/nf-core/mafft_align/tests/main.nf.test b/subworkflows/nf-core/mafft_align/tests/main.nf.test new file mode 100644 index 000000000000..e5bb53aa6423 --- /dev/null +++ b/subworkflows/nf-core/mafft_align/tests/main.nf.test @@ -0,0 +1,36 @@ +nextflow_workflow { + + name "Test Subworkflow MAFFT_ALIGN" + script "../main.nf" + workflow "MAFFT_ALIGN" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/mafft_align" + tag "mafft" + tag "mafft/align" + + + test("seatoxin-ref - fasta") { + + when { + workflow { + """ + input[0] = [ + [ [ id:'test' ] ], // meta map + file(params.modules_testdata_base_path + 'genomics/eukaryotes/anemonia_sulcata/seatoxin-ref.aln', checkIfExists: true), + ] + """ + } + } + then { + assert workflow.success + assertAll( + { assert snapshot( + workflow.out + ).match() } + ) + } + } + +} diff --git a/subworkflows/nf-core/mafft_align/tests/main.nf.test.snap b/subworkflows/nf-core/mafft_align/tests/main.nf.test.snap new file mode 100644 index 000000000000..635c228e4bf3 --- /dev/null +++ b/subworkflows/nf-core/mafft_align/tests/main.nf.test.snap @@ -0,0 +1,39 @@ +{ + "seatoxin-ref - fasta": { + "content": [ + { + "0": [ + [ + [ + { + "id": "test" + } + ], + "[test].fas:md5,d443a4d46c7d85f5ea5f5f73148c6f34" + ] + ], + "1": [ + "versions.yml:md5,e84c35bc0c2b5e69b0e70e5063a04b00" + ], + "alignment": [ + [ + [ + { + "id": "test" + } + ], + "[test].fas:md5,d443a4d46c7d85f5ea5f5f73148c6f34" + ] + ], + "versions": [ + "versions.yml:md5,e84c35bc0c2b5e69b0e70e5063a04b00" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.8" + }, + "timestamp": "2025-12-10T10:56:30.188643" + } +} \ No newline at end of file From e2c915679fc2f209f2d77436b2dc979982f8eab6 Mon Sep 17 00:00:00 2001 From: Adrien Coulier Date: Wed, 10 Dec 2025 16:39:41 +0100 Subject: [PATCH 55/83] Fix missing version from subworkflow snapshot (#9548) --- .../tests/main.nf.test | 1 + .../tests/main.nf.test.snap | 15 +++++ .../tests/main.nf.test | 3 +- .../tests/main.nf.test.snap | 19 ++++-- .../fastq_remove_rrna/tests/main.nf.test | 6 ++ .../fastq_remove_rrna/tests/main.nf.test.snap | 60 +++++++++++++++---- 6 files changed, 89 insertions(+), 15 deletions(-) diff --git a/subworkflows/nf-core/bam_create_som_pon_gatk/tests/main.nf.test b/subworkflows/nf-core/bam_create_som_pon_gatk/tests/main.nf.test index 558f68130922..64bd0bff0e58 100644 --- a/subworkflows/nf-core/bam_create_som_pon_gatk/tests/main.nf.test +++ b/subworkflows/nf-core/bam_create_som_pon_gatk/tests/main.nf.test @@ -51,6 +51,7 @@ nextflow_workflow { then { assertAll( { assert workflow.success }, + { assert snapshot(workflow.out.versions).match("versions") }, { assert snapshot(file(workflow.out.mutect2_vcf.get(0).get(1)).name).match("test1.vcf.gz") }, { assert snapshot(file(workflow.out.mutect2_index.get(0).get(1)).name).match("test1.vcf.gz.tbi") }, { assert snapshot(file(workflow.out.mutect2_stats.get(0).get(1)).name).match("test1.vcf.gz.stats") }, diff --git a/subworkflows/nf-core/bam_create_som_pon_gatk/tests/main.nf.test.snap b/subworkflows/nf-core/bam_create_som_pon_gatk/tests/main.nf.test.snap index 4c0d88a26dad..73c181d5806e 100644 --- a/subworkflows/nf-core/bam_create_som_pon_gatk/tests/main.nf.test.snap +++ b/subworkflows/nf-core/bam_create_som_pon_gatk/tests/main.nf.test.snap @@ -19,6 +19,21 @@ }, "timestamp": "2024-02-14T06:59:54.102164313" }, + "versions": { + "content": [ + [ + "versions.yml:md5,372aff89fa24a61afed05026b9300345", + "versions.yml:md5,4e7c726474b7a321e56c5260ad8ab209", + "versions.yml:md5,4e7c726474b7a321e56c5260ad8ab209", + "versions.yml:md5,b21263bb2f8ab5733906245941e30e77" + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T15:46:00.217316738" + }, "test_panel.vcf.gz.tbi": { "content": [ "test_panel.vcf.gz.tbi" diff --git a/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/tests/main.nf.test b/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/tests/main.nf.test index 3196ed0f18c3..c4bfcc681d28 100644 --- a/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/tests/main.nf.test @@ -486,7 +486,8 @@ nextflow_workflow { { assert bowtie2RrnaCount == 10 }, // 10 reads aligned to rRNA reference { assert snapshot( selines.join('\n').md5(), - processed_ribo_removal_lint_report.md5() + processed_ribo_removal_lint_report.md5(), + workflow.out.versions ).match() } ) } diff --git a/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/tests/main.nf.test.snap index 548176fa9b27..de60230834d6 100644 --- a/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/tests/main.nf.test.snap @@ -50,12 +50,23 @@ "homo_sapiens single-end [fastq] fastp bowtie2": { "content": [ "b423f619ae31c22b2bf99bdcb89bf852", - "5c1e74518dd70e4f1506b4f64da7b5f3" + "5c1e74518dd70e4f1506b4f64da7b5f3", + [ + "versions.yml:md5,32dd6a2d25ace29928423400082ed21e", + "versions.yml:md5,4f417b1f2243b8fdbb4d500d297275d7", + "versions.yml:md5,62a1dcf235b26d36556128000350f873", + "versions.yml:md5,65b00c07a75fb33c090cfdc3caf6c670", + "versions.yml:md5,703785e3662b35a0d9e533f0047fee5c", + "versions.yml:md5,7da162ffef1721b87e11194d10acaeee", + "versions.yml:md5,916a9eda18796248d67f0775546401a1", + "versions.yml:md5,9c1eaf84889a0aa32a7e224bb59cc614", + "versions.yml:md5,e22c32ec91f95bda4130664671ca7cea" + ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-11-28T11:03:31.491281" + "timestamp": "2025-12-10T15:09:04.590361686" } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_remove_rrna/tests/main.nf.test b/subworkflows/nf-core/fastq_remove_rrna/tests/main.nf.test index f0ea51d5d60d..ef1eb9f86a8d 100644 --- a/subworkflows/nf-core/fastq_remove_rrna/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_remove_rrna/tests/main.nf.test @@ -78,6 +78,7 @@ nextflow_workflow { { assert pelines2.size() == 16636 }, { assert sortmernaRrnaCount == 20 }, // 10 pairs = 20 individual reads (100% detection) { assert snapshot( + workflow.out.versions, pelines1.join('\n').md5(), pelines2.join('\n').md5() ).match() } @@ -126,6 +127,7 @@ nextflow_workflow { { assert pelines2.size() == 16648 }, { assert ribodetectorRrnaCount == 7 }, // 7 pairs detected (70% - ML model misses some) { assert snapshot( + workflow.out.versions, sortedLines1.join('\n').md5(), sortedLines2.join('\n').md5() ).match() } @@ -171,6 +173,7 @@ nextflow_workflow { { assert pelines2.size() == 16636 }, { assert bowtie2RrnaCount == 17 }, // 17 mates aligned to rRNA reference { assert snapshot( + workflow.out.versions, pelines1.join('\n').md5(), pelines2.join('\n').md5() ).match() } @@ -233,6 +236,7 @@ nextflow_workflow { { assert selines.size() == 16636 }, // 4159 reads × 4 lines/read { assert bowtie2RrnaCount == 10 }, // 10 reads aligned to rRNA reference { assert snapshot( + workflow.out.versions, selines.join('\n').md5() ).match() } ) @@ -290,6 +294,7 @@ nextflow_workflow { { assert selines.size() == 16636 }, // 4159 reads × 4 lines/read { assert sortmernaRrnaCount == 10 }, // 10 reads detected (100% detection) { assert snapshot( + workflow.out.versions, selines.join('\n').md5() ).match() } ) @@ -333,6 +338,7 @@ nextflow_workflow { // even when the same rRNA databases are provided multiple times assertAll( { assert workflow.success }, + { assert snapshot(workflow.out.versions).match() }, { assert pelines1.size() >= 0 }, // Should have some reads { assert pelines2.size() >= 0 }, // Should have some reads { assert !workflow.stderr.contains("Duplicate entry") }, // No duplicate header errors in stderr diff --git a/subworkflows/nf-core/fastq_remove_rrna/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_remove_rrna/tests/main.nf.test.snap index f9a5fc3feeff..8e7720d50871 100644 --- a/subworkflows/nf-core/fastq_remove_rrna/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_remove_rrna/tests/main.nf.test.snap @@ -1,55 +1,95 @@ { "homo_sapiens single-end [fastq] bowtie2": { "content": [ + [ + "versions.yml:md5,2cfbbdad4c4dcdfacedeb20ec188145b", + "versions.yml:md5,5edeace71a857688bae03f7a5c102caf", + "versions.yml:md5,98dd18ffc97251b8a24e611b27ba12af", + "versions.yml:md5,cb634680924d1a6f4c7de81a23a2e992" + ], "bdea4e3bbdbb7c301ff578b9d8976fb6" ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-11-28T11:51:37.291482561" + "timestamp": "2025-12-10T15:48:50.273951118" }, "homo_sapiens single-end [fastq] sortmerna": { "content": [ + [ + "versions.yml:md5,d375aebf400213ebbd6e104a331b27ae" + ], "bdea4e3bbdbb7c301ff578b9d8976fb6" ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-11-28T11:51:50.835424985" + "timestamp": "2025-12-10T15:49:01.125046076" + }, + "homo_sapiens paired-end [fastq] bowtie2 with duplicate rrna databases": { + "content": [ + [ + "versions.yml:md5,2cfbbdad4c4dcdfacedeb20ec188145b", + "versions.yml:md5,2cfbbdad4c4dcdfacedeb20ec188145b", + "versions.yml:md5,5edeace71a857688bae03f7a5c102caf", + "versions.yml:md5,5edeace71a857688bae03f7a5c102caf", + "versions.yml:md5,98dd18ffc97251b8a24e611b27ba12af", + "versions.yml:md5,a9810676328a1650fc826978ae8eb96b", + "versions.yml:md5,bee00b6ec637b583decca8bd9c9eacd0" + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T15:49:36.940527491" }, "homo_sapiens paired-end [fastq] sortmerna": { "content": [ + [ + "versions.yml:md5,d375aebf400213ebbd6e104a331b27ae" + ], "bdea4e3bbdbb7c301ff578b9d8976fb6", "1b83618177abebeb38c29d2258efdd4f" ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-11-28T11:49:53.980824473" + "timestamp": "2025-12-10T15:48:17.279619846" }, "homo_sapiens paired-end [fastq] ribodetector": { "content": [ + [ + "versions.yml:md5,acaf2e83db2526761adf39c912b0037c" + ], "ec0260bcdeef6af8a9b6d470eafb5603", "a0ef8564218df5741dee81f03db13600" ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-11-29T18:27:41.89909077" + "timestamp": "2025-12-10T15:48:30.322253019" }, "homo_sapiens paired-end [fastq] bowtie2": { "content": [ + [ + "versions.yml:md5,2cfbbdad4c4dcdfacedeb20ec188145b", + "versions.yml:md5,5edeace71a857688bae03f7a5c102caf", + "versions.yml:md5,98dd18ffc97251b8a24e611b27ba12af", + "versions.yml:md5,a9810676328a1650fc826978ae8eb96b", + "versions.yml:md5,bee00b6ec637b583decca8bd9c9eacd0" + ], "4ef4e259208497288aaefaa88770975d", "63198a2af4a4a8fb949b01a8b2c4cb7c" ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.2" }, - "timestamp": "2025-11-28T11:51:24.742227098" + "timestamp": "2025-12-10T15:48:40.498006186" } } \ No newline at end of file From b6868306f5467d1146ca594a10485109c8047c06 Mon Sep 17 00:00:00 2001 From: HD Yi Date: Wed, 10 Dec 2025 09:10:43 -0800 Subject: [PATCH 56/83] New module: whatshap/phase (#9431) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add whatshap phase module * change the vcf-specific test * change test * add versions * remove snapshot * update snapshot * Update modules/nf-core/whatshap/phase/tests/main.nf.test Co-authored-by: Famke Bäuerle <45968370+famosab@users.noreply.github.com> * rm unused args * add snapshot * add ontologies * update the snapshot * add versions to snapshot * fix stub issues * update the test and snap * fix format with "nextflow lint" * fix hardcoded name and file name ambiguity problem --------- Co-authored-by: Famke Bäuerle <45968370+famosab@users.noreply.github.com> --- .../nf-core/whatshap/phase/environment.yml | 7 ++ modules/nf-core/whatshap/phase/main.nf | 63 +++++++++++ modules/nf-core/whatshap/phase/meta.yml | 99 +++++++++++++++++ .../nf-core/whatshap/phase/tests/main.nf.test | 104 ++++++++++++++++++ .../whatshap/phase/tests/main.nf.test.snap | 70 ++++++++++++ 5 files changed, 343 insertions(+) create mode 100644 modules/nf-core/whatshap/phase/environment.yml create mode 100644 modules/nf-core/whatshap/phase/main.nf create mode 100644 modules/nf-core/whatshap/phase/meta.yml create mode 100644 modules/nf-core/whatshap/phase/tests/main.nf.test create mode 100644 modules/nf-core/whatshap/phase/tests/main.nf.test.snap diff --git a/modules/nf-core/whatshap/phase/environment.yml b/modules/nf-core/whatshap/phase/environment.yml new file mode 100644 index 000000000000..389d6871ef48 --- /dev/null +++ b/modules/nf-core/whatshap/phase/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::whatshap=2.8" diff --git a/modules/nf-core/whatshap/phase/main.nf b/modules/nf-core/whatshap/phase/main.nf new file mode 100644 index 000000000000..6d5729607831 --- /dev/null +++ b/modules/nf-core/whatshap/phase/main.nf @@ -0,0 +1,63 @@ +process WHATSHAP_PHASE { + tag "${meta.id}" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'oras://community.wave.seqera.io/library/whatshap:2.8--c3862a4b2ad0f978' + : 'community.wave.seqera.io/library/whatshap:2.8--7fe530bc624a3e5a'}" + + input: + tuple val(meta), path(vcf), path(tbi) + tuple val(meta2), path(bam), path(bai) + tuple val(meta3), path(fasta), path(fai) + + output: + tuple val(meta), path("*.vcf.gz"), emit: vcf + tuple val(meta), path("*.vcf.gz.tbi"), emit: tbi + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + if ("${vcf}" == "${prefix}.vcf" || "${vcf}" == "${prefix}.vcf.gz") { + error("Input and output names are the same, set prefix in module configuration to disambiguate!") + } + """ + whatshap \\ + phase \\ + --output ${prefix}.vcf \\ + --reference ${fasta} \\ + ${args} \\ + ${vcf} \\ + ${bam} + + bgzip ${prefix}.vcf + tabix -p vcf ${prefix}.vcf.gz + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + whatshap: \$(whatshap --version 2>&1 | sed 's/whatshap //g') + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + + if ("${vcf}" == "${prefix}.vcf" || "${vcf}" == "${prefix}.vcf.gz") { + error("Input and output names are the same, set prefix in module configuration to disambiguate!") + } + """ + echo "" | gzip > ${prefix}.vcf.gz + touch ${prefix}.vcf.gz.tbi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + whatshap: \$(whatshap --version 2>&1 | sed 's/whatshap //g') + END_VERSIONS + """ +} diff --git a/modules/nf-core/whatshap/phase/meta.yml b/modules/nf-core/whatshap/phase/meta.yml new file mode 100644 index 000000000000..89233aae3b66 --- /dev/null +++ b/modules/nf-core/whatshap/phase/meta.yml @@ -0,0 +1,99 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "whatshap_phase" +description: Phase variants in a VCF file using long-read sequencing data +keywords: + - phasing + - haplotypes + - vcf + - long-reads + - nanopore + - pacbio +tools: + - whatshap: + description: | + WhatsHap is a software for phasing genomic variants using DNA sequencing + reads, also called read-based phasing or haplotype assembly. + homepage: https://whatshap.readthedocs.io/ + documentation: https://whatshap.readthedocs.io/ + tool_dev_url: https://github.com/whatshap/whatshap + doi: "10.1101/085050" + licence: ["MIT"] + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - vcf: + type: file + description: VCF file with unphased variants (can be gzipped) + pattern: "*.{vcf,vcf.gz}" + - tbi: + type: file + description: VCF index file (optional but recommended) + pattern: "*.{tbi,csi}" + - - meta2: + type: map + description: | + Groovy Map containing bam information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: BAM file with aligned reads + pattern: "*.bam" + - bai: + type: file + description: BAM index file (optional but recommended) + pattern: "*.bai" + - - meta3: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fasta: + type: file + description: Reference genome in FASTA format + pattern: "*.{fa,fasta}" + - fai: + type: file + description: Reference genome index + pattern: "*.fai" + +output: + vcf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*.vcf.gz": + type: file + description: Bgzipped phased VCF file + pattern: "*.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + tbi: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*.vcf.gz.tbi": + type: file + description: Phased VCF index file + pattern: "*.vcf.gz.tbi" + ontologies: + - edam: http://edamontology.org/format_3616 # TBI format + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML + +authors: + - "@haidyi" +maintainers: + - "@haidyi" diff --git a/modules/nf-core/whatshap/phase/tests/main.nf.test b/modules/nf-core/whatshap/phase/tests/main.nf.test new file mode 100644 index 000000000000..5d6ec2b8a9ec --- /dev/null +++ b/modules/nf-core/whatshap/phase/tests/main.nf.test @@ -0,0 +1,104 @@ +nextflow_process { + + name "Test Process WHATSHAP_PHASE" + script "../main.nf" + process "WHATSHAP_PHASE" + + tag "modules" + tag "modules_nfcore" + tag "whatshap" + tag "whatshap/phase" + tag "samtools/faidx" + + setup { + run("SAMTOOLS_FAIDX") { + script "../../../samtools/faidx/main.nf" + process { + """ + input[0] = [ [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome3.fasta', checkIfExists: true) ] + input[1] = [[],[]] + input[2] = false + """ + } + } + } + + test("whatshap - phase - vcf") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/NA03697B2_new.pbmm2.repeats.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/NA03697B2_new.pbmm2.repeats.vcf.gz.csi', checkIfExists: true), + + ] + + input[1] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/bam/NA03697B2_downsampled.pbmm2.repeats.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/bam/NA03697B2_downsampled.pbmm2.repeats.bam.bai', checkIfExists: true), + ] + + input[2] = Channel.of([ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome3.fasta', checkIfExists: true) + ]).join(SAMTOOLS_FAIDX.out.fai) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.summary, + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.versions, + path(process.out.versions[0]).yaml, + ).match() } + ) + } + + } + + test("whatshap - phase - vcf - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/NA03697B2_new.pbmm2.repeats.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/vcf/NA03697B2_new.pbmm2.repeats.vcf.gz.csi', checkIfExists: true), + + ] + + input[1] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/bam/NA03697B2_downsampled.pbmm2.repeats.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pacbio/bam/NA03697B2_downsampled.pbmm2.repeats.bam.bai', checkIfExists: true), + ] + + input[2] = Channel.of([ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome3.fasta', checkIfExists: true) + ]).join(SAMTOOLS_FAIDX.out.fai) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/whatshap/phase/tests/main.nf.test.snap b/modules/nf-core/whatshap/phase/tests/main.nf.test.snap new file mode 100644 index 000000000000..18b00f7fb6b4 --- /dev/null +++ b/modules/nf-core/whatshap/phase/tests/main.nf.test.snap @@ -0,0 +1,70 @@ +{ + "whatshap - phase - vcf - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,eebecfb3d7f284fc7d11c67978bf1994" + ], + "tbi": [ + [ + { + "id": "test" + }, + "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "test" + }, + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,eebecfb3d7f284fc7d11c67978bf1994" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-08T10:09:39.439411781" + }, + "whatshap - phase - vcf": { + "content": [ + "VcfFile [chromosomes=[chr19:45760000-45770300], sampleCount=1, variantCount=1, phased=false, phasedAutodetect=false]", + "e75d1ebbe87d6e55739cacb4e81dcd08", + [ + "versions.yml:md5,eebecfb3d7f284fc7d11c67978bf1994" + ], + { + "WHATSHAP_PHASE": { + "whatshap": 2.8 + } + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-08T10:09:34.591009388" + } +} \ No newline at end of file From 196f22c51f1cde6eb1665dd83af5dd86e233414d Mon Sep 17 00:00:00 2001 From: Joon Klaps Date: Wed, 10 Dec 2025 19:19:29 +0100 Subject: [PATCH 57/83] Bump version cat/cat to pigz 2.8 & rewrite nf-test & topic channel (#9549) * bump version cat/cat * reinclude cat tags for other modules * patch test name & meta.yml * Update main.nf.test --- modules/nf-core/cat/cat/environment.yml | 2 +- modules/nf-core/cat/cat/main.nf | 6 +- modules/nf-core/cat/cat/meta.yml | 31 +- modules/nf-core/cat/cat/tests/main.nf.test | 85 +++--- .../nf-core/cat/cat/tests/main.nf.test.snap | 282 +++++++++++++----- modules/nf-core/cat/cat/tests/nextflow.config | 6 + .../cat/tests/nextflow_unzipped_zipped.config | 6 - .../cat/tests/nextflow_zipped_unzipped.config | 8 - 8 files changed, 286 insertions(+), 140 deletions(-) create mode 100644 modules/nf-core/cat/cat/tests/nextflow.config delete mode 100644 modules/nf-core/cat/cat/tests/nextflow_unzipped_zipped.config delete mode 100644 modules/nf-core/cat/cat/tests/nextflow_zipped_unzipped.config diff --git a/modules/nf-core/cat/cat/environment.yml b/modules/nf-core/cat/cat/environment.yml index 50c2059afb16..985117698a0c 100644 --- a/modules/nf-core/cat/cat/environment.yml +++ b/modules/nf-core/cat/cat/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - conda-forge::pigz=2.3.4 + - conda-forge::pigz=2.8 diff --git a/modules/nf-core/cat/cat/main.nf b/modules/nf-core/cat/cat/main.nf index 2862c64cd9d0..aa72fc4d97cf 100644 --- a/modules/nf-core/cat/cat/main.nf +++ b/modules/nf-core/cat/cat/main.nf @@ -4,15 +4,15 @@ process CAT_CAT { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/pigz:2.3.4' : - 'biocontainers/pigz:2.3.4' }" + 'https://depot.galaxyproject.org/singularity/pigz:2.8' : + 'biocontainers/pigz:2.8' }" input: tuple val(meta), path(files_in) output: tuple val(meta), path("${prefix}"), emit: file_out - path "versions.yml" , emit: versions + tuple val("${task.process}"), val("pigz"), eval("pigz --version 2>&1 | sed 's/pigz //g'"), topic: versions, emit: versions_cat when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/cat/cat/meta.yml b/modules/nf-core/cat/cat/meta.yml index 2a9284d7f107..36a7359bbf93 100644 --- a/modules/nf-core/cat/cat/meta.yml +++ b/modules/nf-core/cat/cat/meta.yml @@ -28,16 +28,33 @@ output: description: Groovy Map containing sample information - ${prefix}: type: file - description: Concatenated file. Will be gzipped if file_out ends with ".gz" + description: Concatenated file. Will be gzipped if file_out ends with + ".gz" pattern: "${file_out}" ontologies: [] + versions_cat: + - - ${task.process}: + type: string + description: The name of the process + - pigz: + type: string + description: The name of the tool + - "pigz --version 2>&1 | sed 's/pigz //g'": + type: eval + description: The expression to obtain the version of the tool + +topics: versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - - ${task.process}: + type: string + description: The name of the process + - pigz: + type: string + description: The name of the tool + - "pigz --version 2>&1 | sed 's/pigz //g'": + type: eval + description: The expression to obtain the version of the tool + authors: - "@erikrikarddaniel" - "@FriederikeHanssen" diff --git a/modules/nf-core/cat/cat/tests/main.nf.test b/modules/nf-core/cat/cat/tests/main.nf.test index 9cb1617883f5..030c6649d02c 100644 --- a/modules/nf-core/cat/cat/tests/main.nf.test +++ b/modules/nf-core/cat/cat/tests/main.nf.test @@ -3,16 +3,14 @@ nextflow_process { name "Test Process CAT_CAT" script "../main.nf" process "CAT_CAT" + tag "modules" tag "modules_nfcore" tag "cat" tag "cat/cat" - test("test_cat_name_conflict") { + test("sarscov2 - genome - error: name conflict") { when { - params { - outdir = "${outputDir}" - } process { """ input[0] = @@ -30,16 +28,13 @@ nextflow_process { assertAll( { assert !process.success }, { assert process.stdout.toString().contains("The name of the input file can't be the same as for the output prefix") }, - { assert snapshot(process.out.versions).match() } + { assert snapshot(process.out).match() } ) } } - test("test_cat_unzipped_unzipped") { + test("sarscov2 - [ fasta, sizes ] - unzipped") { when { - params { - outdir = "${outputDir}" - } process { """ input[0] = @@ -62,11 +57,8 @@ nextflow_process { } - test("test_cat_zipped_zipped") { + test("sarscov2 - [ gff3_gz, maf_gz ] - zipped") { when { - params { - outdir = "${outputDir}" - } process { """ input[0] = @@ -81,25 +73,20 @@ nextflow_process { } } then { - def lines = path(process.out.file_out.get(0).get(1)).linesGzip assertAll( { assert process.success }, - { assert snapshot( - lines[0..5], - lines.size(), - process.out.versions - ).match() + { assert snapshot(process.out).match() } ) } } - test("test_cat_zipped_unzipped") { - config './nextflow_zipped_unzipped.config' + test("sarscov2 - [ gff3_gz, maf_gz ] - unzipped") { + config './nextflow.config' when { params { - outdir = "${outputDir}" + cat_prefix = "cat.txt" } process { """ @@ -124,11 +111,12 @@ nextflow_process { } - test("test_cat_unzipped_zipped") { - config './nextflow_unzipped_zipped.config' + test("sarscov2 - [ fasta, sizes ] - zipped") { + config './nextflow.config' + when { params { - outdir = "${outputDir}" + cat_prefix = "cat.txt.gz" } process { """ @@ -144,24 +132,19 @@ nextflow_process { } } then { - def lines = path(process.out.file_out.get(0).get(1)).linesGzip assertAll( { assert process.success }, - { assert snapshot( - lines[0..5], - lines.size(), - process.out.versions - ).match() - } + { assert snapshot(process.out).match() } ) } } - test("test_cat_one_file_unzipped_zipped") { - config './nextflow_unzipped_zipped.config' + test("sarscov2 - fasta - zipped") { + config './nextflow.config' + when { params { - outdir = "${outputDir}" + cat_prefix = "cat.txt.gz" } process { """ @@ -176,15 +159,33 @@ nextflow_process { } } then { - def lines = path(process.out.file_out.get(0).get(1)).linesGzip assertAll( { assert process.success }, - { assert snapshot( - lines[0..5], - lines.size(), - process.out.versions - ).match() - } + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 - fasta - unzipped - stub") { + options "-stub" + + when { + process { + """ + input[0] = + [ + [ id:'test', single_end:true ], + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + ] + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } ) } } diff --git a/modules/nf-core/cat/cat/tests/main.nf.test.snap b/modules/nf-core/cat/cat/tests/main.nf.test.snap index b7623ee65062..5b4e4cc3d748 100644 --- a/modules/nf-core/cat/cat/tests/main.nf.test.snap +++ b/modules/nf-core/cat/cat/tests/main.nf.test.snap @@ -1,5 +1,5 @@ { - "test_cat_unzipped_unzipped": { + "sarscov2 - [ gff3_gz, maf_gz ] - unzipped": { "content": [ { "0": [ @@ -8,11 +8,15 @@ "id": "test", "single_end": true }, - "test.fasta:md5,f44b33a0e441ad58b2d3700270e2dbe2" + "cat.txt:md5,c439d3b60e7bc03e8802a451a0d9a5d9" ] ], "1": [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" + [ + "CAT_CAT", + "pigz", + "2.8" + ] ], "file_out": [ [ @@ -20,21 +24,25 @@ "id": "test", "single_end": true }, - "test.fasta:md5,f44b33a0e441ad58b2d3700270e2dbe2" + "cat.txt:md5,c439d3b60e7bc03e8802a451a0d9a5d9" ] ], - "versions": [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" + "versions_cat": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2023-10-16T14:32:18.500464399" + "timestamp": "2025-12-10T09:08:31.479828" }, - "test_cat_zipped_unzipped": { + "sarscov2 - fasta - unzipped - stub": { "content": [ { "0": [ @@ -43,11 +51,15 @@ "id": "test", "single_end": true }, - "cat.txt:md5,c439d3b60e7bc03e8802a451a0d9a5d9" + "test.fasta:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "1": [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" + [ + "CAT_CAT", + "pigz", + "2.8" + ] ], "file_out": [ [ @@ -55,93 +67,217 @@ "id": "test", "single_end": true }, - "cat.txt:md5,c439d3b60e7bc03e8802a451a0d9a5d9" + "test.fasta:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" + "versions_cat": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2023-10-16T14:32:49.642741302" + "timestamp": "2025-12-10T16:16:28.118094" }, - "test_cat_zipped_zipped": { + "sarscov2 - [ fasta, sizes ] - zipped": { "content": [ - [ - "MT192765.1\tGenbank\ttranscript\t259\t29667\t.\t+\t.\tID=unknown_transcript_1;geneID=orf1ab;gene_name=orf1ab", - "MT192765.1\tGenbank\tgene\t259\t21548\t.\t+\t.\tParent=unknown_transcript_1", - "MT192765.1\tGenbank\tCDS\t259\t13461\t.\t+\t0\tParent=unknown_transcript_1;exception=\"ribosomal slippage\";gbkey=CDS;gene=orf1ab;note=\"pp1ab;translated=by -1 ribosomal frameshift\";product=\"orf1ab polyprotein\";protein_id=QIK50426.1", - "MT192765.1\tGenbank\tCDS\t13461\t21548\t.\t+\t0\tParent=unknown_transcript_1;exception=\"ribosomal slippage\";gbkey=CDS;gene=orf1ab;note=\"pp1ab;translated=by -1 ribosomal frameshift\";product=\"orf1ab polyprotein\";protein_id=QIK50426.1", - "MT192765.1\tGenbank\tCDS\t21556\t25377\t.\t+\t0\tParent=unknown_transcript_1;gbkey=CDS;gene=S;note=\"structural protein\";product=\"surface glycoprotein\";protein_id=QIK50427.1", - "MT192765.1\tGenbank\tgene\t21556\t25377\t.\t+\t.\tParent=unknown_transcript_1" - ], - 78, - [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" - ] + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "cat.txt.gz:md5,f44b33a0e441ad58b2d3700270e2dbe2" + ] + ], + "1": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ], + "file_out": [ + [ + { + "id": "test", + "single_end": true + }, + "cat.txt.gz:md5,f44b33a0e441ad58b2d3700270e2dbe2" + ] + ], + "versions_cat": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-10T16:15:56.529595" + }, + "sarscov2 - genome - error: name conflict": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "file_out": [ + + ], + "versions_cat": [ + + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-22T11:51:46.802978" + "timestamp": "2025-12-10T16:14:54.496538" }, - "test_cat_name_conflict": { + "sarscov2 - [ fasta, sizes ] - unzipped": { "content": [ - [ - - ] + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fasta:md5,f44b33a0e441ad58b2d3700270e2dbe2" + ] + ], + "1": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ], + "file_out": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fasta:md5,f44b33a0e441ad58b2d3700270e2dbe2" + ] + ], + "versions_cat": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-22T11:51:29.45394" + "timestamp": "2025-12-10T11:26:29.942203" }, - "test_cat_one_file_unzipped_zipped": { + "sarscov2 - [ gff3_gz, maf_gz ] - zipped": { "content": [ - [ - ">MT192765.1 Severe acute respiratory syndrome coronavirus 2 isolate SARS-CoV-2/human/USA/PC00101P/2020, complete genome", - "GTTTATACCTTCCCAGGTAACAAACCAACCAACTTTCGATCTCTTGTAGATCTGTTCTCTAAACGAACTTTAAAATCTGT", - "GTGGCTGTCACTCGGCTGCATGCTTAGTGCACTCACGCAGTATAATTAATAACTAATTACTGTCGTTGACAGGACACGAG", - "TAACTCGTCTATCTTCTGCAGGCTGCTTACGGTTTCGTCCGTGTTGCAGCCGATCATCAGCACATCTAGGTTTTGTCCGG", - "GTGTGACCGAAAGGTAAGATGGAGAGCCTTGTCCCTGGTTTCAACGAGAAAACACACGTCCAACTCAGTTTGCCTGTTTT", - "ACAGGTTCGCGACGTGCTCGTACGTGGCTTTGGAGACTCCGTGGAGGAGGTCTTATCAGAGGCACGTCAACATCTTAAAG" - ], - 374, - [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" - ] + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.gff3.gz:md5,c439d3b60e7bc03e8802a451a0d9a5d9" + ] + ], + "1": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ], + "file_out": [ + [ + { + "id": "test", + "single_end": true + }, + "test.gff3.gz:md5,c439d3b60e7bc03e8802a451a0d9a5d9" + ] + ], + "versions_cat": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-22T11:52:02.774016" + "timestamp": "2025-12-10T11:26:45.679401" }, - "test_cat_unzipped_zipped": { + "sarscov2 - fasta - zipped": { "content": [ - [ - ">MT192765.1 Severe acute respiratory syndrome coronavirus 2 isolate SARS-CoV-2/human/USA/PC00101P/2020, complete genome", - "GTTTATACCTTCCCAGGTAACAAACCAACCAACTTTCGATCTCTTGTAGATCTGTTCTCTAAACGAACTTTAAAATCTGT", - "GTGGCTGTCACTCGGCTGCATGCTTAGTGCACTCACGCAGTATAATTAATAACTAATTACTGTCGTTGACAGGACACGAG", - "TAACTCGTCTATCTTCTGCAGGCTGCTTACGGTTTCGTCCGTGTTGCAGCCGATCATCAGCACATCTAGGTTTTGTCCGG", - "GTGTGACCGAAAGGTAAGATGGAGAGCCTTGTCCCTGGTTTCAACGAGAAAACACACGTCCAACTCAGTTTGCCTGTTTT", - "ACAGGTTCGCGACGTGCTCGTACGTGGCTTTGGAGACTCCGTGGAGGAGGTCTTATCAGAGGCACGTCAACATCTTAAAG" - ], - 375, - [ - "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" - ] + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "cat.txt.gz:md5,6e9fe4042a72f2345f644f239272b7e6" + ] + ], + "1": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ], + "file_out": [ + [ + { + "id": "test", + "single_end": true + }, + "cat.txt.gz:md5,6e9fe4042a72f2345f644f239272b7e6" + ] + ], + "versions_cat": [ + [ + "CAT_CAT", + "pigz", + "2.8" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-22T11:51:57.581523" + "timestamp": "2025-12-10T16:16:12.439911" } } \ No newline at end of file diff --git a/modules/nf-core/cat/cat/tests/nextflow.config b/modules/nf-core/cat/cat/tests/nextflow.config new file mode 100644 index 000000000000..5bc9bf50e349 --- /dev/null +++ b/modules/nf-core/cat/cat/tests/nextflow.config @@ -0,0 +1,6 @@ + +process { + withName: CAT_CAT { + ext.prefix = "${params.cat_prefix}" + } +} diff --git a/modules/nf-core/cat/cat/tests/nextflow_unzipped_zipped.config b/modules/nf-core/cat/cat/tests/nextflow_unzipped_zipped.config deleted file mode 100644 index ec26b0fdc6ec..000000000000 --- a/modules/nf-core/cat/cat/tests/nextflow_unzipped_zipped.config +++ /dev/null @@ -1,6 +0,0 @@ - -process { - withName: CAT_CAT { - ext.prefix = 'cat.txt.gz' - } -} diff --git a/modules/nf-core/cat/cat/tests/nextflow_zipped_unzipped.config b/modules/nf-core/cat/cat/tests/nextflow_zipped_unzipped.config deleted file mode 100644 index fbc79783d5b6..000000000000 --- a/modules/nf-core/cat/cat/tests/nextflow_zipped_unzipped.config +++ /dev/null @@ -1,8 +0,0 @@ - -process { - - withName: CAT_CAT { - ext.prefix = 'cat.txt' - } - -} From 5649f8a11102fa3470c5d8ab6182f0f73484ebe9 Mon Sep 17 00:00:00 2001 From: Sebastian Uhrig Date: Wed, 10 Dec 2025 19:28:39 +0100 Subject: [PATCH 58/83] plastid metagene_generate, make_wiggle, psite (#9482) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * plastid metagene_generate, make_wiggle, psite * pair BAM and BAI files * pair bam and p_offsets * omit optional arguments * metagene generate accepts various input formats * add meta * do not remove variable headers from output files * warning about hard-coded version * make lint happy * make lint happy #2 * plastid/make_wiggle: nf-core standards compliance - Add mapping_rule val input (enum: fiveprime, threeprime, center, fiveprime_variable) - Move output_format to ext.args (optional arg per nf-core standards) - Add validation: error if p_offsets missing with fiveprime_variable - Remove hardcoded --fiveprime_variable - Update meta.yml with mapping_rule input and enum - Update tests with mapping_rule input 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 * adapt meta.yml to new parameters * plastid: consolidate test snapshots and fix reproducibility - Consolidate multiple snapshot assertions into single snapshots per test - Remove snapshots of empty stub files (just check existence) - Exclude non-reproducible PNG from psite snapshots (matplotlib drift) - Format metagene_generate command across multiple lines 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 * plastid/make_wiggle: remove tracks from snapshot Wig files have non-reproducible md5sums across environments. Content is already validated via getText().contains('track'). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 * plastid/psite: remove non-reproducible outputs from snapshot metagene_profiles.txt and p_offsets.txt have non-reproducible md5sums. Content is already validated via getText().contains() checks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: Jonathan Manning Co-authored-by: Claude Opus 4.5 --- .../plastid/make_wiggle/environment.yml | 7 ++ modules/nf-core/plastid/make_wiggle/main.nf | 68 ++++++++++++++ modules/nf-core/plastid/make_wiggle/meta.yml | 77 +++++++++++++++ .../plastid/make_wiggle/tests/main.nf.test | 65 +++++++++++++ .../make_wiggle/tests/main.nf.test.snap | 26 +++++ .../plastid/metagene_generate/environment.yml | 7 ++ .../nf-core/plastid/metagene_generate/main.nf | 48 ++++++++++ .../plastid/metagene_generate/meta.yml | 72 ++++++++++++++ .../metagene_generate/tests/main.nf.test | 55 +++++++++++ .../metagene_generate/tests/main.nf.test.snap | 26 +++++ modules/nf-core/plastid/psite/environment.yml | 7 ++ modules/nf-core/plastid/psite/main.nf | 54 +++++++++++ modules/nf-core/plastid/psite/meta.yml | 94 +++++++++++++++++++ .../nf-core/plastid/psite/tests/main.nf.test | 67 +++++++++++++ .../plastid/psite/tests/main.nf.test.snap | 26 +++++ 15 files changed, 699 insertions(+) create mode 100644 modules/nf-core/plastid/make_wiggle/environment.yml create mode 100644 modules/nf-core/plastid/make_wiggle/main.nf create mode 100644 modules/nf-core/plastid/make_wiggle/meta.yml create mode 100644 modules/nf-core/plastid/make_wiggle/tests/main.nf.test create mode 100644 modules/nf-core/plastid/make_wiggle/tests/main.nf.test.snap create mode 100644 modules/nf-core/plastid/metagene_generate/environment.yml create mode 100644 modules/nf-core/plastid/metagene_generate/main.nf create mode 100644 modules/nf-core/plastid/metagene_generate/meta.yml create mode 100644 modules/nf-core/plastid/metagene_generate/tests/main.nf.test create mode 100644 modules/nf-core/plastid/metagene_generate/tests/main.nf.test.snap create mode 100644 modules/nf-core/plastid/psite/environment.yml create mode 100644 modules/nf-core/plastid/psite/main.nf create mode 100644 modules/nf-core/plastid/psite/meta.yml create mode 100644 modules/nf-core/plastid/psite/tests/main.nf.test create mode 100644 modules/nf-core/plastid/psite/tests/main.nf.test.snap diff --git a/modules/nf-core/plastid/make_wiggle/environment.yml b/modules/nf-core/plastid/make_wiggle/environment.yml new file mode 100644 index 000000000000..86ff4ca20409 --- /dev/null +++ b/modules/nf-core/plastid/make_wiggle/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: + - plastid=0.6.1 diff --git a/modules/nf-core/plastid/make_wiggle/main.nf b/modules/nf-core/plastid/make_wiggle/main.nf new file mode 100644 index 000000000000..78adce16e795 --- /dev/null +++ b/modules/nf-core/plastid/make_wiggle/main.nf @@ -0,0 +1,68 @@ +process PLASTID_MAKE_WIGGLE { + tag "$meta.id" + label "process_single" + + // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/plastid:0.6.1--py39had3e4b6_2': + 'biocontainers/plastid:0.6.1--py39had3e4b6_2' }" + + input: + tuple val(meta), path(bam), path(bam_index), path(p_offsets) + val(mapping_rule) + + output: + tuple val(meta), path("*.{wig,bedgraph}"), emit: tracks + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + if (mapping_rule == 'fiveprime_variable' && !p_offsets) { + error "p_offsets file is required when using mapping_rule 'fiveprime_variable'" + } + def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: "" + def offset_arg = mapping_rule == 'fiveprime_variable' ? "--offset $p_offsets" : "" + def extension = args.contains('--output_format bedgraph') ? "bedgraph" : "wig" + def VERSION = "0.6.1" // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + make_wiggle \\ + --count_files "$bam" \\ + $offset_arg \\ + --${mapping_rule} \\ + -o "$prefix" \\ + $args + + if [ "$extension" = "bedgraph" ]; then + for FILE in *.wig; do + mv "\$FILE" "\${FILE%.wig}.bedgraph" + done + fi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + plastid: $VERSION + END_VERSIONS + """ + + stub: + if (mapping_rule == 'fiveprime_variable' && !p_offsets) { + error "p_offsets file is required when using mapping_rule 'fiveprime_variable'" + } + def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: "" + def extension = args.contains('--output_format bedgraph') ? "bedgraph" : "wig" + def VERSION = "0.6.1" // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + touch ${prefix}_fw.${extension} + touch ${prefix}_rc.${extension} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + plastid: $VERSION + END_VERSIONS + """ +} diff --git a/modules/nf-core/plastid/make_wiggle/meta.yml b/modules/nf-core/plastid/make_wiggle/meta.yml new file mode 100644 index 000000000000..a78feea6c280 --- /dev/null +++ b/modules/nf-core/plastid/make_wiggle/meta.yml @@ -0,0 +1,77 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "plastid_make_wiggle" +description: Create wiggle or bedGraph files from alignment files after applying + a read mapping rule (e.g. to map ribosome-protected footprints at their + P-sites), for visualization in a genome browser +keywords: + - genomics + - riboseq + - psite + - wiggle + - bedgraph +tools: + - "plastid": + description: "Nucleotide-resolution analysis of next-generation sequencing and + genomics data" + homepage: "https://github.com/joshuagryphon/plastid" + documentation: "https://plastid.readthedocs.io/en/latest/" + tool_dev_url: "https://github.com/joshuagryphon/plastid" + doi: "10.1186/s12864-016-3278-x" + licence: ["BSD-3-clause"] + identifier: biotools:plastid + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - bam: + type: file + description: Genome BAM file + pattern: "*.bam" + ontologies: + - edam: http://edamontology.org/format_2572 # BAM + - bam_index: + type: file + description: Genome BAM index file + pattern: "*.bai" + ontologies: + - edam: http://edamontology.org/format_3327 # BAI + - p_offsets: + type: file + description: | + Selected p-site offset for each read length (output from plastid_psite). + Required when mapping_rule is 'fiveprime_variable', otherwise pass empty list []. + pattern: "*_p_offsets.txt" + ontologies: [] + - mapping_rule: + type: string + description: | + Read mapping rule. Use 'fiveprime_variable' with p_offsets file to map reads to P-sites. + enum: ["fiveprime", "threeprime", "center", "fiveprime_variable"] +output: + tracks: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*.{wig,bedgraph}": + type: file + description: wig/bedgraph tracks for forward and reverse strands + pattern: "*.{wig,bedgraph}" + ontologies: + - edam: http://edamontology.org/format_3005 # wig + - edam: http://edamontology.org/format_3583 # bedgraph + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@suhrig" +maintainers: + - "@suhrig" diff --git a/modules/nf-core/plastid/make_wiggle/tests/main.nf.test b/modules/nf-core/plastid/make_wiggle/tests/main.nf.test new file mode 100644 index 000000000000..8aa562ebf25f --- /dev/null +++ b/modules/nf-core/plastid/make_wiggle/tests/main.nf.test @@ -0,0 +1,65 @@ +// nf-core modules test plastid +nextflow_process { + + name "Test Process PLASTID_MAKE_WIGGLE" + script "../main.nf" + process "PLASTID_MAKE_WIGGLE" + + tag "modules" + tag "modules_nfcore" + tag "plastid" + tag "plastid/make_wiggle" + + test("human chr20 bam - fiveprime_variable") { + + when { + process { + """ + input[0] = [ + [ id:'SRX11780887' ], // meta map + file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/aligned_reads/SRX11780887_chr20.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/aligned_reads/SRX11780887_chr20.bam.bai", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/plastid/SRX11780887_p_offsets.txt", checkIfExists: true) + ] + input[1] = 'fiveprime_variable' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.tracks.get(0).get(1).get(0)).getText().contains('track') }, + { assert snapshot(process.out.versions).match() } + ) + } + } + + test("human chr20 bam - fiveprime_variable - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'SRX11780887' ], // meta map + file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/aligned_reads/SRX11780887_chr20.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/aligned_reads/SRX11780887_chr20.bam.bai", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/plastid/SRX11780887_p_offsets.txt", checkIfExists: true) + ] + input[1] = 'fiveprime_variable' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert file(process.out.tracks.get(0).get(1).get(0)).exists() }, + { assert snapshot(process.out.versions).match() } + ) + } + } + +} diff --git a/modules/nf-core/plastid/make_wiggle/tests/main.nf.test.snap b/modules/nf-core/plastid/make_wiggle/tests/main.nf.test.snap new file mode 100644 index 000000000000..0d2f6778ae37 --- /dev/null +++ b/modules/nf-core/plastid/make_wiggle/tests/main.nf.test.snap @@ -0,0 +1,26 @@ +{ + "human chr20 bam - fiveprime_variable": { + "content": [ + [ + "versions.yml:md5,4ecd455575ab11a0ad86dc5e0a6c6959" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-10T12:36:00.352824" + }, + "human chr20 bam - fiveprime_variable - stub": { + "content": [ + [ + "versions.yml:md5,4ecd455575ab11a0ad86dc5e0a6c6959" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-10T12:26:10.353895" + } +} \ No newline at end of file diff --git a/modules/nf-core/plastid/metagene_generate/environment.yml b/modules/nf-core/plastid/metagene_generate/environment.yml new file mode 100644 index 000000000000..86ff4ca20409 --- /dev/null +++ b/modules/nf-core/plastid/metagene_generate/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: + - plastid=0.6.1 diff --git a/modules/nf-core/plastid/metagene_generate/main.nf b/modules/nf-core/plastid/metagene_generate/main.nf new file mode 100644 index 000000000000..ef3faeaaa254 --- /dev/null +++ b/modules/nf-core/plastid/metagene_generate/main.nf @@ -0,0 +1,48 @@ +process PLASTID_METAGENE_GENERATE { + tag "$annotation" + label "process_low" + + // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/plastid:0.6.1--py39had3e4b6_2': + 'biocontainers/plastid:0.6.1--py39had3e4b6_2' }" + + input: + tuple val(meta), path(annotation) + + output: + tuple val(meta), path("*_rois.txt"), emit: rois_txt + tuple val(meta), path("*_rois.bed"), emit: rois_bed + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def VERSION = "0.6.1" // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + metagene generate \\ + "${annotation.baseName}" \\ + --annotation_files "$annotation" \\ + $args + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + plastid: $VERSION + END_VERSIONS + """ + + stub: + def VERSION = "0.6.1" // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + touch ${annotation.baseName}_rois.txt + touch ${annotation.baseName}_rois.bed + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + plastid: $VERSION + END_VERSIONS + """ +} diff --git a/modules/nf-core/plastid/metagene_generate/meta.yml b/modules/nf-core/plastid/metagene_generate/meta.yml new file mode 100644 index 000000000000..8034234add82 --- /dev/null +++ b/modules/nf-core/plastid/metagene_generate/meta.yml @@ -0,0 +1,72 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "plastid_metagene_generate" +description: Compute a metagene profile of read alignments, counts, or + quantitative data over one or more regions of interest, optionally + applying a mapping rule +keywords: + - genomics + - riboseq + - psite +tools: + - "plastid": + description: "Nucleotide-resolution analysis of next-generation sequencing and genomics data" + homepage: "https://github.com/joshuagryphon/plastid" + documentation: "https://plastid.readthedocs.io/en/latest/" + tool_dev_url: "https://github.com/joshuagryphon/plastid" + doi: "10.1186/s12864-016-3278-x" + licence: ["BSD-3-clause"] + identifier: biotools:plastid + +input: + - - meta: + type: map + description: | + Map containing reference information for the reference genome annotation file + e.g. `[ id:'Ensembl human v.111' ]` + - annotation: + type: file + description: annotation file of reference genome (BED, bigBed, GTF, GFF3) + pattern: "*.{bed,bigbed,gtf,gff3}" + ontologies: + - edam: http://edamontology.org/format_3003 # BED + - edam: http://edamontology.org/format_3004 # bigBed + - edam: http://edamontology.org/format_2306 # GTF + - edam: http://edamontology.org/format_1975 # GFF3 +output: + rois_txt: + - - meta: + type: map + description: | + Map containing reference information for the reference genome annotation file + e.g. `[ id:'Ensembl human v.111' ]` + - "*_rois.txt": + type: file + description: Tab-delimited text file describing the maximal spanning + window for each gene + pattern: "*_rois.txt" + ontologies: [] + rois_bed: + - - meta: + type: map + description: | + Map containing reference information for the reference genome annotation file + e.g. `[ id:'Ensembl human v.111' ]` + - "*_rois.bed": + type: file + description: | + Maximal spanning windows in BED format for visualization in a genome + browser. The thickly-rendered portion of a window indicates its landmark. + pattern: "*_rois.bed" + ontologies: + - edam: http://edamontology.org/format_3003 # BED + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@suhrig" +maintainers: + - "@suhrig" diff --git a/modules/nf-core/plastid/metagene_generate/tests/main.nf.test b/modules/nf-core/plastid/metagene_generate/tests/main.nf.test new file mode 100644 index 000000000000..2f491337dea0 --- /dev/null +++ b/modules/nf-core/plastid/metagene_generate/tests/main.nf.test @@ -0,0 +1,55 @@ +// nf-core modules test plastid +nextflow_process { + + name "Test Process PLASTID_METAGENE_GENERATE" + script "../main.nf" + process "PLASTID_METAGENE_GENERATE" + + tag "modules" + tag "modules_nfcore" + tag "plastid" + tag "plastid/metagene_generate" + + test("human chr20 gtf") { + + when { + process { + """ + input[0] = [[id:'homo_sapiens_chr20'], file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/Homo_sapiens.GRCh38.111_chr20.gtf", checkIfExists: true)] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.rois_txt.get(0).get(1)).getText().contains('ENSG') }, + { assert path(process.out.rois_bed.get(0).get(1)).getText().contains('ENSG') }, + { assert snapshot(process.out.versions).match('versions') } + ) + } + } + + test("human chr20 gtf -stub") { + + options "-stub" + + when { + process { + """ + input[0] = [[id:'homo_sapiens_chr20'], file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/Homo_sapiens.GRCh38.111_chr20.gtf", checkIfExists: true)] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert file(process.out.rois_txt.get(0).get(1)).exists() }, + { assert file(process.out.rois_bed.get(0).get(1)).exists() }, + { assert snapshot(process.out.versions).match() } + ) + } + } + +} diff --git a/modules/nf-core/plastid/metagene_generate/tests/main.nf.test.snap b/modules/nf-core/plastid/metagene_generate/tests/main.nf.test.snap new file mode 100644 index 000000000000..9fd426fbe90c --- /dev/null +++ b/modules/nf-core/plastid/metagene_generate/tests/main.nf.test.snap @@ -0,0 +1,26 @@ +{ + "human chr20 gtf -stub": { + "content": [ + [ + "versions.yml:md5,3507c6516efe03f85ff066089c7a4b1b" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-10T12:45:35.749835" + }, + "versions": { + "content": [ + [ + "versions.yml:md5,3507c6516efe03f85ff066089c7a4b1b" + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-08T10:46:58.250416821" + } +} \ No newline at end of file diff --git a/modules/nf-core/plastid/psite/environment.yml b/modules/nf-core/plastid/psite/environment.yml new file mode 100644 index 000000000000..86ff4ca20409 --- /dev/null +++ b/modules/nf-core/plastid/psite/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: + - plastid=0.6.1 diff --git a/modules/nf-core/plastid/psite/main.nf b/modules/nf-core/plastid/psite/main.nf new file mode 100644 index 000000000000..79389ce7a5c4 --- /dev/null +++ b/modules/nf-core/plastid/psite/main.nf @@ -0,0 +1,54 @@ +process PLASTID_PSITE { + tag "$meta.id" + label "process_single" + + // WARN: Version information not provided by tool on CLI. Please update version string below when bumping container versions. + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/plastid:0.6.1--py39had3e4b6_2': + 'biocontainers/plastid:0.6.1--py39had3e4b6_2' }" + + input: + tuple val(meta), path(bam), path(bam_index) + tuple val(meta2), path(rois_txt) + + output: + tuple val(meta), path("*_metagene_profiles.txt"), emit: metagene_profiles + tuple val(meta), path("*_p_offsets.png") , emit: p_offsets_png + tuple val(meta), path("*_p_offsets.txt") , emit: p_offsets + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: "" + def VERSION = "0.6.1" // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + psite \ + "$rois_txt" \\ + "$prefix" \\ + --count_files "$bam" \\ + $args + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + plastid: $VERSION + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + def VERSION = "0.6.1" // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + touch ${prefix}_metagene_profiles.txt + touch ${prefix}_p_offsets.png + touch ${prefix}_p_offsets.txt + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + plastid: $VERSION + END_VERSIONS + """ +} diff --git a/modules/nf-core/plastid/psite/meta.yml b/modules/nf-core/plastid/psite/meta.yml new file mode 100644 index 000000000000..cf0ec666a98e --- /dev/null +++ b/modules/nf-core/plastid/psite/meta.yml @@ -0,0 +1,94 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "plastid_psite" +description: Estimate position of ribosomal P-site within ribosome profiling + read alignments as a function of read length +keywords: + - genomics + - riboseq + - psite +tools: + - "plastid": + description: "Nucleotide-resolution analysis of next-generation sequencing and genomics data" + homepage: "https://github.com/joshuagryphon/plastid" + documentation: "https://plastid.readthedocs.io/en/latest/" + tool_dev_url: "https://github.com/joshuagryphon/plastid" + doi: "10.1186/s12864-016-3278-x" + licence: ["BSD-3-clause"] + identifier: biotools:plastid + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - bam: + type: file + description: Genome BAM file + pattern: "*.bam" + ontologies: + - edam: http://edamontology.org/format_2572 # BAM + - bam_index: + type: file + description: Genome BAM index file + pattern: "*.bai" + ontologies: + - edam: http://edamontology.org/format_3327 # BAI + - - meta2: + type: map + description: | + Map containing reference information for the reference genome GTF file + e.g. `[ id:'Ensembl human v.111' ]` + - rois_txt: + type: file + description: | + Tab-delimited text file describing the maximal spanning + window for each gene (output from plastid_metagene_generate) + pattern: "*.txt" + ontologies: [] +output: + metagene_profiles: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*_metagene_profiles.txt": + type: file + description: Matrix containing metagene profile for each read length + pattern: "*_metagene_profiles.txt" + ontologies: [] + p_offsets_png: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*_p_offsets.png": + type: file + description: Graphical illustration of metagene profiles + pattern: "*_p_offsets.png" + ontologies: + - edam: http://edamontology.org/format_3603 # PNG + p_offsets: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*_p_offsets.txt": + type: file + description: Selected p-site offset for each read length + pattern: "*_p_offsets.txt" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@suhrig" +maintainers: + - "@suhrig" diff --git a/modules/nf-core/plastid/psite/tests/main.nf.test b/modules/nf-core/plastid/psite/tests/main.nf.test new file mode 100644 index 000000000000..a7b78ff91564 --- /dev/null +++ b/modules/nf-core/plastid/psite/tests/main.nf.test @@ -0,0 +1,67 @@ +// nf-core modules test plastid +nextflow_process { + + name "Test Process PLASTID_PSITE" + script "../main.nf" + process "PLASTID_PSITE" + + tag "modules" + tag "modules_nfcore" + tag "plastid" + tag "plastid/psite" + + test("human chr20 bam") { + + when { + process { + """ + input[0] = [ + [ id:'SRX11780887' ], // meta map + file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/aligned_reads/SRX11780887_chr20.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/aligned_reads/SRX11780887_chr20.bam.bai", checkIfExists: true) + ] + input[1] = [[id:'homo_sapiens_chr20'], file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/plastid/Homo_sapiens.GRCh38.111_chr20_rois.txt", checkIfExists: true)] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.metagene_profiles.get(0).get(1)).getText().contains('28-mers') }, + { assert file(process.out.p_offsets_png.get(0).get(1)).exists() }, + { assert path(process.out.p_offsets.get(0).get(1)).getText().contains("length\tp_offset") }, + { assert snapshot(process.out.versions).match() } + ) + } + } + + test("human chr20 bam -stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'SRX11780887' ], // meta map + file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/aligned_reads/SRX11780887_chr20.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/aligned_reads/SRX11780887_chr20.bam.bai", checkIfExists: true) + ] + input[1] = [[id:'homo_sapiens_chr20'], file(params.modules_testdata_base_path + "genomics/homo_sapiens/riboseq_expression/plastid/Homo_sapiens.GRCh38.111_chr20_rois.txt", checkIfExists: true)] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert file(process.out.metagene_profiles.get(0).get(1)).exists() }, + { assert file(process.out.p_offsets_png.get(0).get(1)).exists() }, + { assert file(process.out.p_offsets.get(0).get(1)).exists() }, + { assert snapshot(process.out.versions).match() } + ) + } + } + +} diff --git a/modules/nf-core/plastid/psite/tests/main.nf.test.snap b/modules/nf-core/plastid/psite/tests/main.nf.test.snap new file mode 100644 index 000000000000..c2a3532c8376 --- /dev/null +++ b/modules/nf-core/plastid/psite/tests/main.nf.test.snap @@ -0,0 +1,26 @@ +{ + "human chr20 bam -stub": { + "content": [ + [ + "versions.yml:md5,f0a577bc6782d64582ef1c52b5b47ad7" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-10T12:46:13.713244" + }, + "human chr20 bam": { + "content": [ + [ + "versions.yml:md5,f0a577bc6782d64582ef1c52b5b47ad7" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-10T12:46:07.654842" + } +} \ No newline at end of file From a0e5a8b395ef6f7bb6303fb73208d98f2ca45d3d Mon Sep 17 00:00:00 2001 From: Felix Lenner <52530259+fellen31@users.noreply.github.com> Date: Wed, 10 Dec 2025 20:21:49 +0100 Subject: [PATCH 59/83] Add index and threads to trgt/merge (#9545) --- modules/nf-core/trgt/merge/main.nf | 15 +- modules/nf-core/trgt/merge/meta.yml | 11 ++ modules/nf-core/trgt/merge/tests/main.nf.test | 89 ++++++++- .../trgt/merge/tests/main.nf.test.snap | 170 +++++++++++++++++- 4 files changed, 260 insertions(+), 25 deletions(-) diff --git a/modules/nf-core/trgt/merge/main.nf b/modules/nf-core/trgt/merge/main.nf index 24c4d59a13ba..1b0e407049f5 100644 --- a/modules/nf-core/trgt/merge/main.nf +++ b/modules/nf-core/trgt/merge/main.nf @@ -14,6 +14,7 @@ process TRGT_MERGE { output: tuple val(meta), path("*.{vcf,vcf.gz,bcf,bcf.gz}"), emit: vcf + tuple val(meta), path("*.{tbi,csi}") , emit: index, optional: true tuple val("${task.process}"), val('trgt'), eval("trgt --version | sed 's/.* //g'"), emit: versions_trgt, topic: versions when: @@ -32,15 +33,11 @@ process TRGT_MERGE { """ trgt merge \\ + --threads ${task.cpus} \\ $args \\ $reference \\ $output \\ --vcf ${vcfs} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - trgt: \$(trgt --version |& sed '1!d ; s/trgt //') - END_VERSIONS """ stub: @@ -52,12 +49,10 @@ process TRGT_MERGE { args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : "vcf" def create_cmd = extension.endsWith(".gz") ? "echo '' | gzip >" : "touch" + def index_type = extension == "vcf.gz" ? "tbi" : extension == "bcf.gz" ? "csi" : '' + def create_index = args.contains("--write-index") && extension.endsWith(".gz") ? "touch ${prefix}.${extension}.${index_type}" : '' """ $create_cmd ${prefix}.${extension} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - trgt: \$(trgt --version |& sed '1!d ; s/trgt //') - END_VERSIONS + $create_index """ } diff --git a/modules/nf-core/trgt/merge/meta.yml b/modules/nf-core/trgt/merge/meta.yml index 72ed57d50a93..c1bb9cec6b08 100644 --- a/modules/nf-core/trgt/merge/meta.yml +++ b/modules/nf-core/trgt/merge/meta.yml @@ -72,6 +72,17 @@ output: description: "Merged output file" pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" ontologies: [] + index: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*.{tbi,csi}": + type: file + description: "Index of merged output file" + pattern: "*.{tbi,csi}" + ontologies: [] versions_trgt: - - ${task.process}: type: string diff --git a/modules/nf-core/trgt/merge/tests/main.nf.test b/modules/nf-core/trgt/merge/tests/main.nf.test index 5b3697a1e233..c9b5bf8b005e 100644 --- a/modules/nf-core/trgt/merge/tests/main.nf.test +++ b/modules/nf-core/trgt/merge/tests/main.nf.test @@ -95,6 +95,7 @@ nextflow_process { path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.sampleCount, + process.out.index, process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) @@ -120,6 +121,7 @@ nextflow_process { path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.sampleCount, + process.out.index, process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) @@ -132,6 +134,7 @@ nextflow_process { input[0] = BCFTOOLS_SORT.out.vcf .join(BCFTOOLS_SORT.out.tbi) .first() + .map { meta, vcf, tbi -> [ [ id : 'test' ], vcf, tbi ] } input[1] = GUNZIP.out.gunzip input[2] = SAMTOOLS_FAIDX.out.fai """ @@ -143,16 +146,17 @@ nextflow_process { ) } } - test("homo sapiens - 1 VCF - --force-single") { + test("homo sapiens - 1 VCF - --force-single --output-type z --write-index") { when { params { - trgt_merge_args = "--force-single" + trgt_merge_args = "--force-single --output-type z --write-index" } process { """ input[0] = BCFTOOLS_SORT.out.vcf .join(BCFTOOLS_SORT.out.tbi) .first() + .map { meta, vcf, tbi -> [ [ id : 'test' ], vcf, tbi ] } input[1] = GUNZIP.out.gunzip input[2] = SAMTOOLS_FAIDX.out.fai """ @@ -165,11 +169,87 @@ nextflow_process { path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, path(process.out.vcf.get(0).get(1)).vcf.summary, path(process.out.vcf.get(0).get(1)).vcf.sampleCount, + process.out.index, process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } } + test("homo sapiens - 1 VCF - --force-single --output-type b --write-index") { + when { + params { + trgt_merge_args = "--force-single --output-type b --write-index" + } + process { + """ + input[0] = BCFTOOLS_SORT.out.vcf + .join(BCFTOOLS_SORT.out.tbi) + .first() + .map { meta, vcf, tbi -> [ [ id : 'test' ], vcf, tbi ] } + input[1] = GUNZIP.out.gunzip + input[2] = SAMTOOLS_FAIDX.out.fai + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.vcf.get(0).get(1)).name, + process.out.index, + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + } + test("homo sapiens - 2 VCFs - tbi index - stub") { + options "-stub" + when { + params { + trgt_merge_args = "--output-type z --write-index" + } + process { + """ + input[0] = BCFTOOLS_SORT.out.vcf + .join(BCFTOOLS_SORT.out.tbi) + .map { meta, vcf, tbi -> [ [ id : 'test' ], vcf, tbi ] } + .groupTuple() + input[1] = [[],[]] + input[2] = [[],[]] + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + test("homo sapiens - 2 VCFs - csi index - stub") { + options "-stub" + when { + params { + trgt_merge_args = "--output-type b --write-index" + } + process { + """ + input[0] = BCFTOOLS_SORT.out.vcf + .join(BCFTOOLS_SORT.out.tbi) + .map { meta, vcf, tbi -> [ [ id : 'test' ], vcf, tbi ] } + .groupTuple() + input[1] = [[],[]] + input[2] = [[],[]] + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } test("homo sapiens - 2 VCFs - stub") { options "-stub" when { @@ -187,10 +267,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot( - process.out, - process.out.findAll { key, val -> key.startsWith("versions")} - ).match() } + { assert snapshot(process.out).match() } ) } } diff --git a/modules/nf-core/trgt/merge/tests/main.nf.test.snap b/modules/nf-core/trgt/merge/tests/main.nf.test.snap index 4168ceba4ce0..7c2cf06b934d 100644 --- a/modules/nf-core/trgt/merge/tests/main.nf.test.snap +++ b/modules/nf-core/trgt/merge/tests/main.nf.test.snap @@ -1,9 +1,39 @@ { + "homo sapiens - 1 VCF - --force-single --output-type b --write-index": { + "content": [ + "test.bcf.gz", + [ + [ + { + "id": "test" + }, + "test.bcf.gz.csi:md5,25edb1e7fca90690371848b7c01b9631" + ] + ], + { + "versions_trgt": [ + [ + "TRGT_MERGE", + "trgt", + "5.0.0-e9acee0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-10T15:42:21.803640957" + }, "homo sapiens - 2 VCFs - reference": { "content": [ "497b2c70fe41ad0c67c5fc4e1f281227", "VcfFile [chromosomes=[chr22], sampleCount=2, variantCount=1, phased=false, phasedAutodetect=false]", 2, + [ + + ], { "versions_trgt": [ [ @@ -18,13 +48,16 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-10T13:39:09.705242328" + "timestamp": "2025-12-10T15:36:01.2063008" }, "homo sapiens - 2 VCFs": { "content": [ "497b2c70fe41ad0c67c5fc4e1f281227", "VcfFile [chromosomes=[chr22], sampleCount=2, variantCount=1, phased=false, phasedAutodetect=false]", 2, + [ + + ], { "versions_trgt": [ [ @@ -39,9 +72,9 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-10T13:39:03.993142872" + "timestamp": "2025-12-10T15:35:55.048303885" }, - "homo sapiens - 2 VCFs - stub": { + "homo sapiens - 2 VCFs - tbi index - stub": { "content": [ { "0": [ @@ -49,22 +82,38 @@ { "id": "test" }, - "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "1": [ + [ + { + "id": "test" + }, + "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ [ "TRGT_MERGE", "trgt", "5.0.0-e9acee0" ] ], + "index": [ + [ + { + "id": "test" + }, + "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], "vcf": [ [ { "id": "test" }, - "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "versions_trgt": [ @@ -74,8 +123,46 @@ "5.0.0-e9acee0" ] ] - }, + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-10T15:36:25.238838671" + }, + "homo sapiens - 2 VCFs - stub": { + "content": [ { + "0": [ + [ + { + "id": "test" + }, + "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + [ + "TRGT_MERGE", + "trgt", + "5.0.0-e9acee0" + ] + ], + "index": [ + + ], + "vcf": [ + [ + { + "id": "test" + }, + "test.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], "versions_trgt": [ [ "TRGT_MERGE", @@ -89,13 +176,21 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-10T13:39:26.797540928" + "timestamp": "2025-12-10T15:36:37.406628045" }, - "homo sapiens - 1 VCF - --force-single": { + "homo sapiens - 1 VCF - --force-single --output-type z --write-index": { "content": [ "bad30e1ef353973510fcf4125d127a13", "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=1, phased=false, phasedAutodetect=false]", 1, + [ + [ + { + "id": "test" + }, + "test.vcf.gz.tbi:md5,bd5b91195c6b4b92b1727a170a2656e4" + ] + ], { "versions_trgt": [ [ @@ -110,6 +205,63 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-10T13:39:21.394392963" + "timestamp": "2025-12-10T15:42:15.567594151" + }, + "homo sapiens - 2 VCFs - csi index - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.bcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + "TRGT_MERGE", + "trgt", + "5.0.0-e9acee0" + ] + ], + "index": [ + [ + { + "id": "test" + }, + "test.bcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "test" + }, + "test.bcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_trgt": [ + [ + "TRGT_MERGE", + "trgt", + "5.0.0-e9acee0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-10T15:36:31.142452836" } } \ No newline at end of file From 6b2c2fb7e733cabd9b18d718278193acf7c231d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Wed, 10 Dec 2025 23:34:25 +0100 Subject: [PATCH 60/83] Fix test path modification (#9465) * Update bcftools * Update bcftools csq * Update somalier ancestry * Update bcftools pluginfilltags * Update cnvnator * Update snap cnvnator * Fix extract somalier sbwf * Update snapshot * Update md5 * Fix linting * Upd snapshot * Upd snapshot * Upd snapshot * Upd snapshot --------- Co-authored-by: LouisLeNezet --- .../bcftools/concat/tests/main.nf.test | 68 +++++++++---------- .../bcftools/concat/tests/main.nf.test.snap | 44 ++++++------ .../bcftools/concat/tests/nextflow.config | 2 +- .../concat/tests/vcf_gz_index_csi.config | 2 +- .../nf-core/bcftools/csq/tests/main.nf.test | 2 +- .../bcftools/csq/tests/main.nf.test.snap | 8 +-- .../pluginfilltags/tests/main.nf.test | 8 +-- .../pluginfilltags/tests/main.nf.test.snap | 8 +-- .../cnvnator/cnvnator/tests/main.nf.test | 4 +- modules/nf-core/cnvnator/convert2vcf/main.nf | 2 + .../cnvnator/convert2vcf/tests/main.nf.test | 5 +- .../convert2vcf/tests/main.nf.test.snap | 30 ++------ .../somalier/ancestry/tests/main.nf.test | 4 +- .../tests/main.nf.test | 20 +++--- 14 files changed, 95 insertions(+), 112 deletions(-) diff --git a/modules/nf-core/bcftools/concat/tests/main.nf.test b/modules/nf-core/bcftools/concat/tests/main.nf.test index 442f4b4e892e..9c4e4baf0a15 100644 --- a/modules/nf-core/bcftools/concat/tests/main.nf.test +++ b/modules/nf-core/bcftools/concat/tests/main.nf.test @@ -19,12 +19,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz', checkIfExists: true), - 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.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz.csi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -50,12 +50,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz', checkIfExists: true), - 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.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz.csi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -87,12 +87,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz', checkIfExists: true), - 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.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz.csi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -124,12 +124,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz', checkIfExists: true), - 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.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz.csi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -162,8 +162,8 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz', checkIfExists: true), - 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.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [] ] @@ -191,12 +191,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz', checkIfExists: true), - 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.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz.csi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -223,12 +223,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz', checkIfExists: true), - 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.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz.csi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -256,12 +256,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz', checkIfExists: true), - 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.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz.csi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ @@ -289,12 +289,12 @@ nextflow_process { input[0] = [ [ id:'test3' ], // meta map [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz', checkIfExists: true), - 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.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz.csi', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) ] ] """ diff --git a/modules/nf-core/bcftools/concat/tests/main.nf.test.snap b/modules/nf-core/bcftools/concat/tests/main.nf.test.snap index b82169c9a35c..8d1a6363b832 100644 --- a/modules/nf-core/bcftools/concat/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/concat/tests/main.nf.test.snap @@ -6,7 +6,7 @@ { "id": "test3" }, - "test3_vcf.vcf.gz:md5,85db49dd1629d60e1165f491df6348f6" + "test3_vcf.vcf.gz:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" ] ], [ @@ -25,10 +25,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-15T11:26:25.259752" + "timestamp": "2025-11-26T16:53:25.503018154" }, "homo_sapiens - [[vcf1, vcf2], []]": { "content": [ @@ -38,7 +38,7 @@ { "id": "test3" }, - "test3.vcf:md5,bba76244f79c4e307bd0c4c09095885f" + "test3.vcf:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" ] ], "1": [ @@ -61,7 +61,7 @@ { "id": "test3" }, - "test3.vcf:md5,bba76244f79c4e307bd0c4c09095885f" + "test3.vcf:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" ] ], "versions": [ @@ -70,10 +70,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-15T10:03:17.250013" + "timestamp": "2025-11-26T16:56:01.364652383" }, "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - stub": { "content": [ @@ -182,7 +182,7 @@ { "id": "test3" }, - "test3_vcf.vcf.gz:md5,85db49dd1629d60e1165f491df6348f6" + "test3_vcf.vcf.gz:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" ] ], [ @@ -201,10 +201,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-15T11:26:31.742638" + "timestamp": "2025-11-26T16:53:33.38516503" }, "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]]": { "content": [ @@ -214,7 +214,7 @@ { "id": "test3" }, - "test3.vcf:md5,bba76244f79c4e307bd0c4c09095885f" + "test3.vcf:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" ] ], "1": [ @@ -237,7 +237,7 @@ { "id": "test3" }, - "test3.vcf:md5,bba76244f79c4e307bd0c4c09095885f" + "test3.vcf:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" ] ], "versions": [ @@ -246,10 +246,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-15T10:29:33.203302" + "timestamp": "2025-11-26T16:55:30.850726912" }, "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index": { "content": [ @@ -258,7 +258,7 @@ { "id": "test3" }, - "test3_vcf.vcf.gz:md5,85db49dd1629d60e1165f491df6348f6" + "test3_vcf.vcf.gz:md5,0b4986bbb6bdc9e0ee12ba09e70092e9" ] ], [ @@ -277,10 +277,10 @@ ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-15T11:26:17.482474" + "timestamp": "2025-11-26T16:53:18.091429133" }, "homo_sapiens - [[vcf1, vcf2], [tbi1, tbi2]] - vcf_gz_index_tbi - stub": { "content": [ diff --git a/modules/nf-core/bcftools/concat/tests/nextflow.config b/modules/nf-core/bcftools/concat/tests/nextflow.config index c6a5142a2691..1d5fee9eb562 100644 --- a/modules/nf-core/bcftools/concat/tests/nextflow.config +++ b/modules/nf-core/bcftools/concat/tests/nextflow.config @@ -1,3 +1,3 @@ process { - ext.args = "--no-version" + ext.args = "--no-version -a" } diff --git a/modules/nf-core/bcftools/concat/tests/vcf_gz_index_csi.config b/modules/nf-core/bcftools/concat/tests/vcf_gz_index_csi.config index afa03d74e25c..2455b1457abc 100644 --- a/modules/nf-core/bcftools/concat/tests/vcf_gz_index_csi.config +++ b/modules/nf-core/bcftools/concat/tests/vcf_gz_index_csi.config @@ -1,4 +1,4 @@ process { ext.prefix = { "${meta.id}_vcf" } - ext.args = "--output-type z --write-index=csi --no-version --allow-overlaps" + ext.args = "--output-type z --write-index=csi --no-version --allow-overlaps -a" } diff --git a/modules/nf-core/bcftools/csq/tests/main.nf.test b/modules/nf-core/bcftools/csq/tests/main.nf.test index 52229c9e6740..d5cfa92a5479 100644 --- a/modules/nf-core/bcftools/csq/tests/main.nf.test +++ b/modules/nf-core/bcftools/csq/tests/main.nf.test @@ -17,7 +17,7 @@ nextflow_process { """ input[0] = [ [ id:'test' ], - 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_GIAB.chr21_22.vcf.gz', checkIfExists: true) ] input[1] = [ [ : ], // meta map diff --git a/modules/nf-core/bcftools/csq/tests/main.nf.test.snap b/modules/nf-core/bcftools/csq/tests/main.nf.test.snap index 02d2ac4bac81..b73c1da3b80d 100644 --- a/modules/nf-core/bcftools/csq/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/csq/tests/main.nf.test.snap @@ -1,15 +1,15 @@ { "homo_sapiens": { "content": [ - "876b0b2fe3971805ff1d546775efe5f", + "a048c8564339aa411b019310f5a84326", [ "versions.yml:md5,05afacd9179e80fd0d23218033c3aca9" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-15T12:03:18.948435" + "timestamp": "2025-11-26T16:58:26.677826042" } } \ No newline at end of file diff --git a/modules/nf-core/bcftools/pluginfilltags/tests/main.nf.test b/modules/nf-core/bcftools/pluginfilltags/tests/main.nf.test index d36fcd1eb533..084c647e668d 100644 --- a/modules/nf-core/bcftools/pluginfilltags/tests/main.nf.test +++ b/modules/nf-core/bcftools/pluginfilltags/tests/main.nf.test @@ -24,8 +24,8 @@ nextflow_process { """ input[0] = Channel.of([ [id:'NA12878', region:"chr22:16570065-16609999"], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + 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] = [] @@ -119,8 +119,8 @@ nextflow_process { """ input[0] = Channel.of([ [id:'NA12878', region:"chr22:16570065-16609999"], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + 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] = [] diff --git a/modules/nf-core/bcftools/pluginfilltags/tests/main.nf.test.snap b/modules/nf-core/bcftools/pluginfilltags/tests/main.nf.test.snap index bf49b1e2e566..49187d93e79a 100644 --- a/modules/nf-core/bcftools/pluginfilltags/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/pluginfilltags/tests/main.nf.test.snap @@ -1,17 +1,17 @@ { "homo_sapiens - vcf": { "content": [ - "da09a942b1e3c0226208880743d3dd07", + "d986322f4617ed952c7fcf6ed61e7983", "NA12878.vcf.gz.csi", [ "versions.yml:md5,3eb4d1bb1b803aeb4d38e826dc83b8b2" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-09-15T12:08:35.564113" + "timestamp": "2025-11-26T17:05:08.490151651" }, "homo_sapiens - vcf - samples": { "content": [ diff --git a/modules/nf-core/cnvnator/cnvnator/tests/main.nf.test b/modules/nf-core/cnvnator/cnvnator/tests/main.nf.test index 9ce0ca70683d..09312c46186f 100644 --- a/modules/nf-core/cnvnator/cnvnator/tests/main.nf.test +++ b/modules/nf-core/cnvnator/cnvnator/tests/main.nf.test @@ -17,8 +17,8 @@ nextflow_process { """ input[0] = [ [id:'test',single_end:false],// meta map - 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) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.bam', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.bam.bai', checkIfExists:true) ] input[1] = [[:],[]] input[2] = [[:],[]] diff --git a/modules/nf-core/cnvnator/convert2vcf/main.nf b/modules/nf-core/cnvnator/convert2vcf/main.nf index ffbdf0f13fe5..6319498dd9e8 100644 --- a/modules/nf-core/cnvnator/convert2vcf/main.nf +++ b/modules/nf-core/cnvnator/convert2vcf/main.nf @@ -36,6 +36,8 @@ process CNVNATOR_CONVERT2VCF { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" """ + echo ${args} + touch ${prefix}.vcf cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test b/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test index bd0895f311e0..0652c8a7c127 100644 --- a/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test +++ b/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test @@ -101,7 +101,10 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out.versions, + path(process.out.vcf[0][1]).vcf.variantsMD5 + ).match() } ) } } diff --git a/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test.snap b/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test.snap index d7764d38a5f4..65eee5ac64d6 100644 --- a/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test.snap +++ b/modules/nf-core/cnvnator/convert2vcf/tests/main.nf.test.snap @@ -1,32 +1,10 @@ { "test_cnvnator_convert2vcf": { "content": [ - { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.vcf:md5,d237cf67c66dbc8509d324e623a7d569" - ] - ], - "1": [ - "versions.yml:md5,647a1ccc9e74133a2256ce82377310fc" - ], - "vcf": [ - [ - { - "id": "test", - "single_end": false - }, - "test.vcf:md5,d237cf67c66dbc8509d324e623a7d569" - ] - ], - "versions": [ - "versions.yml:md5,647a1ccc9e74133a2256ce82377310fc" - ] - } + [ + "versions.yml:md5,647a1ccc9e74133a2256ce82377310fc" + ], + "b47837c71432a5ffc854c7936b5966d0" ], "meta": { "nf-test": "0.9.2", diff --git a/modules/nf-core/somalier/ancestry/tests/main.nf.test b/modules/nf-core/somalier/ancestry/tests/main.nf.test index a705b680eef7..d9866051e461 100644 --- a/modules/nf-core/somalier/ancestry/tests/main.nf.test +++ b/modules/nf-core/somalier/ancestry/tests/main.nf.test @@ -57,8 +57,8 @@ nextflow_process { """ input[0] = [ [id:"NA12878"], - 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_GIAB.chr22.vcf.gz.csi', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true) ] input[1] = [ [id: "hg38"], diff --git a/subworkflows/nf-core/vcf_extract_relate_somalier/tests/main.nf.test b/subworkflows/nf-core/vcf_extract_relate_somalier/tests/main.nf.test index 90d8b3f8a759..119fd7efffbc 100644 --- a/subworkflows/nf-core/vcf_extract_relate_somalier/tests/main.nf.test +++ b/subworkflows/nf-core/vcf_extract_relate_somalier/tests/main.nf.test @@ -27,7 +27,7 @@ nextflow_workflow { """ input[0] = Channel.of([ [id:"test"], - 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_GIAB.chr21_22.vcf.gz', checkIfExists: true), [], 1 ]) @@ -53,8 +53,8 @@ nextflow_workflow { """ input[0] = Channel.of([ [id:"test"], - 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_GIAB.chr22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), 1 ]) input[1] = Channel.of([ [id: "Hg38"], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists:true)]) @@ -88,7 +88,7 @@ nextflow_workflow { input[0] = Channel.of([ [id:"test"], - 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_GIAB.chr21_22.vcf.gz', checkIfExists: true), [], 1 ]) @@ -125,7 +125,7 @@ nextflow_workflow { input[0] = Channel.of( [ [id:"test", common:"test"], - 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_GIAB.chr21_22.vcf.gz', checkIfExists: true), [], 2 ], @@ -168,7 +168,7 @@ nextflow_workflow { input[0] = Channel.of( [ [id:"test"], - 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_GIAB.chr21_22.vcf.gz', checkIfExists: true), [], 1 ], @@ -204,11 +204,11 @@ nextflow_workflow { input[0] = Channel.of([ [id:"test"], [ - 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_GIAB.chr21_22.vcf.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA24385_sv.vcf.gz', checkIfExists: true) ], [ - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz.csi', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA24385_sv.vcf.gz.tbi', checkIfExists: true) ] ]) @@ -255,7 +255,7 @@ nextflow_workflow { input[0] = Channel.of( [ [id:"test", common:"test"], - 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_GIAB.chr21_22.vcf.gz', checkIfExists: true), [], [] ], @@ -299,7 +299,7 @@ nextflow_workflow { input[0] = Channel.of( [ [id:"test", common:"test"], - 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_GIAB.chr21_22.vcf.gz', checkIfExists: true), [], [] ], From ea2d4f00e90093336d6621d08fc0fe384a521256 Mon Sep 17 00:00:00 2001 From: Dongze He <171858310+an-altosian@users.noreply.github.com> Date: Wed, 10 Dec 2025 21:14:50 -0800 Subject: [PATCH 61/83] Update xenium ranger modules and subworkflows (#9525) * update xeniumranger modules to use xeniumranger v4.0 * update xeniumranger modules to use xeniumranger v4.0 * fix: update xeniumranger import-segmentation tests and logic * update test compute resource spec to follow 10x website * remove extra file * fix: apply topic channels and update meta.yml structure for xeniumranger * fix: update meta.yml structure to satisfy schema * fix: align meta.yml with topic versions blog post example * fix: update meta.yml topics structure to satisfy schema validation * fix: automated lint fix for meta.yml topics structure * fix: use standard container definition syntax * fix: apply topic versions to rename module * fix: apply topic versions and meta.yml schema fixes for xeniumranger modules and subworkflows * untrack files * remove test config files for github workflow * remove config def in tests * remove config def in tests * Update tests and snapshots for xeniumranger modules and subworkflows * remove subworkflows for xeniumranger * remove subworkflows for xeniumranger * fix: update test template * fix relabel meta.yml * make prek hppy * make prek hppy * make prek hppy * update import-segmentation doc * update import-segmentation doc * fix oncologies * Fix snapshot file key order for rename and resegment modules * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * comment out config * fix: make prek happy * fix typo * remove test files --------- Co-authored-by: Dongze He <32473855+DongzeHE@users.noreply.github.com> Co-authored-by: Sameesh Kher Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- modules/nf-core/xeniumranger/.gitignore | 0 modules/nf-core/xeniumranger/Dockerfile | 12 +- modules/nf-core/xeniumranger/README.md | 2 +- .../xeniumranger/import-segmentation/main.nf | 81 ++--- .../xeniumranger/import-segmentation/meta.yml | 164 ++++++---- .../import-segmentation/tests/main.nf.test | 297 +++--------------- .../tests/main.nf.test.snap | 122 ++----- .../import-segmentation/tests/nextflow.config | 0 modules/nf-core/xeniumranger/relabel/main.nf | 41 +-- modules/nf-core/xeniumranger/relabel/meta.yml | 68 ++-- .../xeniumranger/relabel/tests/main.nf.test | 76 ++--- .../relabel/tests/main.nf.test.snap | 59 ++-- .../relabel/tests/nextflow.config | 0 modules/nf-core/xeniumranger/rename/main.nf | 42 +-- modules/nf-core/xeniumranger/rename/meta.yml | 68 ++-- .../xeniumranger/rename/tests/main.nf.test | 49 +-- .../rename/tests/main.nf.test.snap | 76 +++-- .../xeniumranger/rename/tests/nextflow.config | 0 .../nf-core/xeniumranger/resegment/main.nf | 51 +-- .../nf-core/xeniumranger/resegment/meta.yml | 75 +++-- .../xeniumranger/resegment/tests/main.nf.test | 62 ++-- .../resegment/tests/main.nf.test.snap | 46 ++- .../resegment/tests/nextflow.config | 0 23 files changed, 564 insertions(+), 827 deletions(-) delete mode 100644 modules/nf-core/xeniumranger/.gitignore delete mode 100644 modules/nf-core/xeniumranger/import-segmentation/tests/nextflow.config delete mode 100644 modules/nf-core/xeniumranger/relabel/tests/nextflow.config delete mode 100644 modules/nf-core/xeniumranger/rename/tests/nextflow.config delete mode 100644 modules/nf-core/xeniumranger/resegment/tests/nextflow.config diff --git a/modules/nf-core/xeniumranger/.gitignore b/modules/nf-core/xeniumranger/.gitignore deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/modules/nf-core/xeniumranger/Dockerfile b/modules/nf-core/xeniumranger/Dockerfile index daa3c965c5e0..1bcc0aad53a6 100644 --- a/modules/nf-core/xeniumranger/Dockerfile +++ b/modules/nf-core/xeniumranger/Dockerfile @@ -10,20 +10,20 @@ RUN apt-get update --allow-releaseinfo-change \ # copy over xeniumranger # the latest version of the xeniumranger tool has been downloaded from https://www.10xgenomics.com/support/software/xenium-ranger/downloads -COPY xeniumranger-3.0.1.tar.gz /xeniumranger-3.0.1.tar.gz +COPY xeniumranger-4.0.0.tar.gz /xeniumranger-4.0.0.tar.gz # install xenium ranger -RUN tar -xzvf /xeniumranger-3.0.1.tar.gz && \ - rm /xeniumranger-3.0.1.tar.gz +RUN tar -xzvf /xeniumranger-4.0.0.tar.gz && \ + rm /xeniumranger-4.0.0.tar.gz # Set environment variables -# ENV PATH="xeniumranger-xenium3.0/bin:$PATH" +# ENV PATH="xeniumranger-xenium4.0/bin:$PATH" # multistage to reduce image size FROM ubuntu:20.04 # Set environment variables -ENV PATH="/xeniumranger-xenium3.0/bin:$PATH" +ENV PATH="/xeniumranger-xenium4.0/bin:$PATH" # copy over xenium from builder -COPY --from=builder /xeniumranger-xenium3.0 /xeniumranger-xenium3.0/ +COPY --from=builder /xeniumranger-xenium4.0 /xeniumranger-xenium4.0/ diff --git a/modules/nf-core/xeniumranger/README.md b/modules/nf-core/xeniumranger/README.md index 9bbe56b01c29..fbfdb0173f24 100644 --- a/modules/nf-core/xeniumranger/README.md +++ b/modules/nf-core/xeniumranger/README.md @@ -5,7 +5,7 @@ Xenium Ranger is a commercial tool from 10X Genomics. The container provided for 1. Navigate to the appropriate download page. - [Xenium Ranger](https://www.10xgenomics.com/support/software/xenium-ranger/downloads): download the tar ball of the desired Xenium Ranger version with `curl` or `wget`. Place this file in the same folder where the Dockerfile lies. 2. Edit the Dockerfile. Update the Xenium Ranger versions in this line: - (current version for xenium ranger is fixated at [3.0.1](https://www.10xgenomics.com/support/software/xenium-ranger/downloads) in the dockerfile) + (current version for xenium ranger is fixated at [4.0.0](https://www.10xgenomics.com/support/software/xenium-ranger/downloads) in the dockerfile) 3. Create and test the container: diff --git a/modules/nf-core/xeniumranger/import-segmentation/main.nf b/modules/nf-core/xeniumranger/import-segmentation/main.nf index 50b17272a16c..264b8a72ef63 100644 --- a/modules/nf-core/xeniumranger/import-segmentation/main.nf +++ b/modules/nf-core/xeniumranger/import-segmentation/main.nf @@ -2,80 +2,67 @@ process XENIUMRANGER_IMPORT_SEGMENTATION { tag "$meta.id" label 'process_high' - container "nf-core/xeniumranger:3.0.1" + container "nf-core/xeniumranger:4.0" input: - tuple val(meta), path(xenium_bundle) - val(expansion_distance) - path(coordinate_transform) - path(nuclei) - path(cells) - path(transcript_assignment) - path(viz_polygons) + tuple val(meta), path(xenium_bundle, stageAs: "bundle/"), path(transcript_assignment), path(viz_polygons), path(nuclei), path(cells), path(coordinate_transform), val(units) output: - tuple val(meta), path("**/outs/**"), emit: outs - path "versions.yml", emit: versions + tuple val(meta), path("${prefix}"), emit: outs + tuple val("${task.process}"), val("xeniumranger"), eval("xeniumranger -V | sed -e 's/.*xenium-//'"), emit: versions_xeniumranger, topic: versions when: task.ext.when == null || task.ext.when script: + // Exit if running this module with -profile conda / -profile mamba if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "XENIUMRANGER_IMPORT-SEGMENTATION module does not support Conda. Please use Docker / Singularity / Podman instead." + error "XENIUMRANGER_IMPORT_SEGMENTATION module does not support Conda. Please use Docker / Singularity / Podman instead." } - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - // image based segmentation options - def expansion_distance = expansion_distance ? "--expansion-distance=\"${expansion_distance}\"": "" // expansion distance (default - 5, range - 0 - 100) - def coordinate_transform = coordinate_transform ? "--coordinate-transform=\"${coordinate_transform}\"": "" + prefix = task.ext.prefix ?: "${meta.id}" - def nuclei_detection = nuclei ? "--nuclei=\"${nuclei}\"": "" - def cells = cells ? "--cells=\"${cells}\"": "" + // nuclei and cells are for image segmentation results + // transcript_assignment and viz_polygons are for transcript assignment results + // they are mutually exclusive + if ((nuclei || cells) && (transcript_assignment || viz_polygons)) { + error "--nuclei and --cells are for image segmentation results, which are mutually exclusive with --transcript-assignment and --viz-polygons for transcript assignment results. Please use only one of them." + } - // transcript based segmentation - def transcript_assignment = transcript_assignment ? "--transcript-assignment=\"${transcript_assignment}\"": "" - def viz_polygons = viz_polygons ? "--viz-polygons=\"${viz_polygons}\"":"" + def assembled_args = [] + if (task.ext.args) { assembled_args << task.ext.args.trim() } + if (nuclei) { assembled_args << "--nuclei=\"${nuclei}\"" } + if (cells) { assembled_args << "--cells=\"${cells}\"" } + if (transcript_assignment) { assembled_args << "--transcript-assignment=\"${transcript_assignment}\"" } + if (viz_polygons) { assembled_args << "--viz-polygons=\"${viz_polygons}\"" } + if (coordinate_transform) { + assembled_args << "--coordinate-transform=\"${coordinate_transform}\"" + // if coordinate_transform is provided, units must be microns + assembled_args << "--units=\"microns\"" + } else if (units) { + assembled_args << "--units=\"${units}\"" + } - // shared argument - def units = coordinate_transform ? "--units=microns": "--units=pixels" + def args = assembled_args ? assembled_args.join(" \\\n ") : "" """ xeniumranger import-segmentation \\ - --id="${prefix}" \\ + --id="XENIUMRANGER_IMPORT_SEGMENTATION" \\ --xenium-bundle="${xenium_bundle}" \\ --localcores=${task.cpus} \\ --localmem=${task.memory.toGiga()} \\ - ${coordinate_transform} \\ - ${nuclei_detection} \\ - ${cells} \\ - ${expansion_distance} \\ - ${transcript_assignment} \\ - ${viz_polygons} \\ - ${units} \\ ${args} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - xeniumranger: \$(xeniumranger -V | sed -e "s/xeniumranger-/- /g") - END_VERSIONS + rm -rf "${prefix}" + mv XENIUMRANGER_IMPORT_SEGMENTATION/outs "${prefix}" """ stub: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "XENIUMRANGER_IMPORT-SEGMENTATION module does not support Conda. Please use Docker / Singularity / Podman instead." - } - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" """ - mkdir -p "${prefix}/outs/" - touch "${prefix}/outs/fake_file.txt" - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - xeniumranger: \$(xeniumranger -V | sed -e "s/xeniumranger-/- /g") - END_VERSIONS + mkdir -p "${prefix}" + touch "${prefix}/experiment.xenium" """ + } diff --git a/modules/nf-core/xeniumranger/import-segmentation/meta.yml b/modules/nf-core/xeniumranger/import-segmentation/meta.yml index 5aefa1c61087..e222df582a05 100644 --- a/modules/nf-core/xeniumranger/import-segmentation/meta.yml +++ b/modules/nf-core/xeniumranger/import-segmentation/meta.yml @@ -1,9 +1,14 @@ name: xeniumranger_import_segmentation -description: The xeniumranger import-segmentation module allows you to specify 2D - nuclei and/or cell segmentation results for assigning transcripts to cells and recalculate - all Xenium Onboard Analysis (XOA) outputs that depend on segmentation. Segmentation - results can be generated by community-developed tools or prior Xenium segmentation - result. +description: | + The xeniumranger import-segmentation module runs `xeniumranger import-segmentation` + to recompute Xenium Onboard Analysis outputs using external segmentation results. + It supports two execution modes mirroring the Xenium Ranger CLI: an image-based + mode that accepts nuclei and/or cell masks (TIFF/NPY) or GeoJSON polygons together + with optional coordinate transforms and unit definitions, and a transcript-based + mode that ingests Baysor-style transcript assignment CSV files plus visualization + polygons. Use the image-based inputs when providing label masks or polygons, or + switch to the transcript-based inputs when supplying transcript-level assignments + so the appropriate command-line arguments are passed to Xenium Ranger. keywords: - spatial - segmentation @@ -28,66 +33,109 @@ input: type: map description: | Groovy Map containing run information - e.g. [id:'xenium_bundle_path'] + e.g. [ id:'xenium_sample' ] - xenium_bundle: type: directory - description: Path to the xenium output bundle generated by the Xenium Onboard - Analysis pipeline - - expansion_distance: - type: integer - description: Nuclei boundary expansion distance in µm. Only for use when nucleus - segmentation provided as input. Default-5 (accepted range 0 - 100) - - coordinate_transform: - type: file - description: Image alignment file containing similarity transform matrix e.g., - the _imagealignment.csv file exported from Xenium Explorer - ontologies: [] - - nuclei: - type: file - description: | - Label mask (TIFF or NPY), polygons of nucleus segmentations (GeoJSON FeatureCollection), or Xenium Onboard Analysis cells.zarr.zip (the nucleus masks as input). - --nuclei will use nucleusGeometry polygon if it exists in the GeoJSON (i.e., for QuPath-like GeoJSON files), - or geometry if it does not. Error if --transcript-assignment argument is used. - ontologies: [] - - cells: - type: file - description: | - Label mask (TIFF or NPY), polygons of cell segmentations (GeoJSON FeatureCollection), or Xenium Onboard Analysis cells.zarr.zip (the cell masks as input). - Features with a non-cell objectType will be ignored. Error if --transcript-assignment argument is used. - In Xenium Ranger v2.0, --nuclei no longer needs to be used with --cells. - ontologies: [] - - transcript_assignment: - type: file - description: | - Transcript CSV with cell assignment from Baysor v0.6. Error if --cells or --nuclei arguments are used. - ontologies: [] - - viz_polygons: - type: file - description: | - Cell boundary polygons (GeoJSON) for visualization from Baysor v0.6. Required if --transcript-assignment argument used. Error if --cells or --nuclei arguments used. - ontologies: [] + description: Path to the Xenium output bundle generated by the Xenium + Onboard Analysis pipeline + - transcript_assignment: + type: file + optional: true + description: | + Transcript assignment CSV with cell assignment, such as from Baysor v0.6, (transcript-based mode). + Mutually exclusive with image-based inputs (`nuclei`, `cells`). Required when using + transcript-based mode. Passed to `--transcript-assignment`. + pattern: "*.csv" + ontologies: + - edam: http://edamontology.org/format_3752 # CSV + - viz_polygons: + type: file + optional: true + description: | + Cell boundary polygons (GeoJSON) for visualization, such as from Baysor v0.6 (transcript-based mode). + Mutually exclusive with image-based inputs (`nuclei`, `cells`). Required when using + `transcript_assignment`. Passed to `--viz-polygons`. + pattern: "*.{json,geojson}" + ontologies: + - edam: http://edamontology.org/format_3464 # JSON + - nuclei: + type: file + optional: true + description: | + Nucleus segmentation input as label mask (TIFF/NPY), polygons (GeoJSON), or Xenium Onboard + Analysis cells.zarr.zip (image-based mode). + Mutually exclusive with transcript-based inputs + (`transcript_assignment`, `viz_polygons`). Passed to `--nuclei`. + pattern: "*.{tif,tiff,npy,json,geojson,zarr.zip}" + ontologies: + - edam: http://edamontology.org/format_4003 # NumPy format + - edam: http://edamontology.org/format_3464 # JSON + - cells: + type: file + optional: true + description: | + Cell segmentation input as label mask (TIFF/NPY), polygons (GeoJSON), or Xenium Onboard + Analysis cells.zarr.zip (image-based mode). + Mutually exclusive with transcript-based inputs + (`transcript_assignment`, `viz_polygons`). Passed to `--cells`. + pattern: "*.{tif,tiff,npy,json,geojson,zarr.zip}" + ontologies: + - edam: http://edamontology.org/format_4003 # NumPy format + - edam: http://edamontology.org/format_3464 # JSON + - coordinate_transform: + type: file + optional: true + description: | + Image alignment file containing similarity transform matrix (e.g., `_imagealignment.csv` from + Xenium Explorer). Only used with image-based mode inputs (`nuclei`, `cells`). `units` will be automatically set to "microns". Passed to `--coordinate-transform`. + pattern: "*.csv" + ontologies: + - edam: http://edamontology.org/format_3752 # CSV + - units: + type: string + optional: true + description: | + Units for segmentation results. Must be one of two options: "microns" (physical space) or + "pixels" (pixel space). Can be used with both image-based and transcript-based modes. + Default: "pixels". Must be "microns" if `coordinate_transform` is used. For Baysor v0.6 + inputs, must be "microns". Passed to `--units`. + enum: + - "microns" + - "pixels" output: outs: - - meta: - type: file - description: Files containing the outputs of Cell Ranger, see official 10X - Genomics documentation for a complete list - pattern: "${meta.id}/outs/*" - ontologies: [] - - "**/outs/**": - type: file - description: Files containing the outputs of xenium ranger, see official 10X - Genomics documentation for a complete list of outputs - pattern: "${meta.id}/outs/*" - ontologies: [] + type: map + description: Groovy Map containing sample information e.g. [ id:'test' ] + - ${prefix}: + type: directory + description: Directory containing the output xenium bundle of Xenium + Ranger + pattern: "${prefix}" + versions_xeniumranger: + - - ${task.process}: + type: string + description: The process the versions were collected from + - xeniumranger: + type: string + description: The tool name + - xeniumranger -V | sed -e 's/.*xenium-//': + type: string + description: The command used to generate the version of the tool +topics: versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - - ${task.process}: + type: string + description: The process the versions were collected from + - xeniumranger: + type: string + description: The tool name + - xeniumranger -V | sed -e 's/.*xenium-//': + type: string + description: The command used to generate the version of the tool authors: - "@khersameesh24" + - "@dongzehe" maintainers: - "@khersameesh24" + - "@dongzehe" diff --git a/modules/nf-core/xeniumranger/import-segmentation/tests/main.nf.test b/modules/nf-core/xeniumranger/import-segmentation/tests/main.nf.test index 6e2826eba480..3a8616c1c470 100644 --- a/modules/nf-core/xeniumranger/import-segmentation/tests/main.nf.test +++ b/modules/nf-core/xeniumranger/import-segmentation/tests/main.nf.test @@ -3,7 +3,6 @@ nextflow_process { name "Test Process XENIUMRANGER_IMPORT_SEGMENTATION" script "../main.nf" process "XENIUMRANGER_IMPORT_SEGMENTATION" - config "./nextflow.config" tag "modules" tag "modules_nfcore" @@ -11,296 +10,70 @@ nextflow_process { tag "xeniumranger/import-segmentation" tag "unzip" + setup { - run("UNZIP") { - script "modules/nf-core/unzip/main.nf" - process { - """ - input[0] = [[], file('https://raw.githubusercontent.com/nf-core/test-datasets/spatialxe/Xenium_Prime_Mouse_Ileum_tiny_outs.zip', checkIfExists: true)] - """ - } - } - } - test("xeniumranger import-segmentation nuclei npy") { - when { + run("UNZIP") { + script "modules/nf-core/unzip/main.nf" process { """ - input[0] = Channel.of([ - [id: "test_xeniumranger_import-segmentation"], - ]).combine(UNZIP.out.unzipped_archive.map { it[1] }) - input[1] = 0 - input[2] = [] - input[3] = UNZIP.out.unzipped_archive.map { it[1] } + "/segmentations/nuclei.npy" - input[4] = [] - input[5] = [] - input[6] = [] + input[0] = [[], file('https://raw.githubusercontent.com/nf-core/test-datasets/spatialxe/Xenium_V1_Protein_Human_Kidney_tiny_outs.zip', checkIfExists: true)] """ } } - then { - assertAll( - { assert process.success }, - { assert snapshot( - process.out.versions, - process.out.outs.get(0).get(1).findAll { file(it).name !in [ - 'analysis_summary.html', - 'metrics_summary.csv', - 'cell_boundaries.csv.gz', - 'cell_boundaries.parquet', - 'nucleus_boundaries.csv.gz', - 'nucleus_boundaries.parquet', - 'cells.csv.gz', - 'cells.parquet', - 'cells.zarr.zip', - 'transcripts.parquet', - 'transcripts.zarr.zip', - 'clusters.csv', - 'differential_expression.csv', - 'components.csv', - 'projection.csv', - 'variance.csv', - 'analysis.zarr.zip', - 'experiment.xenium', - 'cell_feature_matrix.zarr.zip' - ]} - ).match() - }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'analysis_summary.html' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'metrics_summary.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cell_boundaries.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cell_boundaries.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'nucleus_boundaries.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'nucleus_boundaries.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.zarr.zip' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'transcripts.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'clusters.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'differential_expression.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'components.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'projection.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'variance.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'analysis.zarr.zip' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'experiment.xenium' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cell_feature_matrix.zarr.zip' }).exists() }, - ) - } - } - - test("xeniumranger import-segmentation nuclei tif") { - when { - process { - """ - input[0] = Channel.of([ - [id: "test_xeniumranger_import-segmentation"], - ]).combine(UNZIP.out.unzipped_archive.map { it[1] }) - input[1] = 0 - input[2] = [] - input[3] = UNZIP.out.unzipped_archive.map { it[1] } + "/segmentations/nuclei.npy" - input[4] = [] - input[5] = [] - input[6] = [] - """ - } - } - then { - assertAll( - { assert process.success }, - { assert snapshot( - process.out.versions, - process.out.outs.get(0).get(1).findAll { file(it).name !in [ - 'analysis_summary.html', - 'metrics_summary.csv', - 'cell_boundaries.csv.gz', - 'cell_boundaries.parquet', - 'nucleus_boundaries.csv.gz', - 'nucleus_boundaries.parquet', - 'cells.csv.gz', - 'cells.parquet', - 'cells.zarr.zip', - 'transcripts.parquet', - 'transcripts.zarr.zip', - 'clusters.csv', - 'differential_expression.csv', - 'components.csv', - 'projection.csv', - 'variance.csv', - 'analysis.zarr.zip', - 'experiment.xenium', - 'cell_feature_matrix.zarr.zip' - ]} - ).match() - }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'analysis_summary.html' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'metrics_summary.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cell_boundaries.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cell_boundaries.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'nucleus_boundaries.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'nucleus_boundaries.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.zarr.zip' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'transcripts.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'clusters.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'differential_expression.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'components.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'projection.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'variance.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'analysis.zarr.zip' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'experiment.xenium' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cell_feature_matrix.zarr.zip' }).exists() }, - ) - } } - test("xeniumranger import-segmentation segmentation csv") { + test("xeniumranger import-segmentation nuclei") { when { process { """ - input[0] = Channel.of([ - [id: "test_xeniumranger_import-segmentation"], - ]).combine(UNZIP.out.unzipped_archive.map { it[1] }) - input[1] = 0 - input[2] = UNZIP.out.unzipped_archive.map { it[1] } + "/segmentations/imagealignment.csv" - input[3] = [] - input[4] = [] - input[5] = UNZIP.out.unzipped_archive.map { it[1] } + "/segmentations/segmentation.csv" - input[6] = UNZIP.out.unzipped_archive.map { it[1] } + "/segmentations/segmentation_polygons.json" + input[0] = UNZIP.out.unzipped_archive + .map { _, bundle -> + [ + [id: "test_xeniumranger_import-segmentation"], + bundle, + [], + [], + bundle + "/cells.zarr.zip", + [], + [], + [] + ] + } """ } } - then { - assertAll( - { assert process.success }, - { assert snapshot( - process.out.versions, - process.out.outs.get(0).get(1).findAll { file(it).name !in [ - 'analysis_summary.html', - 'metrics_summary.csv', - 'cell_boundaries.csv.gz', - 'cell_boundaries.parquet', - 'nucleus_boundaries.csv.gz', - 'nucleus_boundaries.parquet', - 'cells.csv.gz', - 'cells.parquet', - 'cells.zarr.zip', - 'transcripts.parquet', - 'transcripts.zarr.zip', - 'clusters.csv', - 'differential_expression.csv', - 'components.csv', - 'projection.csv', - 'variance.csv', - 'analysis.zarr.zip', - 'experiment.xenium', - 'cell_feature_matrix.zarr.zip' - ]} - ).match() - }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'analysis_summary.html' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'metrics_summary.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cell_boundaries.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cell_boundaries.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'nucleus_boundaries.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'nucleus_boundaries.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.zarr.zip' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'transcripts.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'clusters.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'differential_expression.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'components.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'projection.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'variance.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'analysis.zarr.zip' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'experiment.xenium' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cell_feature_matrix.zarr.zip' }).exists() }, - ) - } - } - test("xeniumranger import-segmentation") { - when { - process { - """ - input[0] = Channel.of([ - [id: "test_xeniumranger_import-segmentation"], - ]).combine(UNZIP.out.unzipped_archive.map { it[1] }) - input[1] = 0 - input[2] = [] - input[3] = UNZIP.out.unzipped_archive.map { it[1] } + "/cells.zarr.zip" - input[4] = [] - input[5] = [] - input[6] = [] - """ - } - } then { assertAll( { assert process.success }, - { assert snapshot( - process.out.versions, - process.out.outs.get(0).get(1).findAll { file(it).name !in [ - 'analysis_summary.html', - 'metrics_summary.csv', - 'cell_boundaries.csv.gz', - 'cell_boundaries.parquet', - 'nucleus_boundaries.csv.gz', - 'nucleus_boundaries.parquet', - 'cells.csv.gz', - 'cells.parquet', - 'cells.zarr.zip', - 'transcripts.parquet', - 'transcripts.zarr.zip', - 'clusters.csv', - 'differential_expression.csv', - 'components.csv', - 'projection.csv', - 'variance.csv', - 'analysis.zarr.zip', - 'experiment.xenium', - 'cell_feature_matrix.zarr.zip' - ]} - ).match() - }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'analysis_summary.html' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'metrics_summary.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cell_boundaries.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cell_boundaries.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'nucleus_boundaries.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'nucleus_boundaries.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.zarr.zip' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'transcripts.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'clusters.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'differential_expression.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'components.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'projection.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'variance.csv' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'analysis.zarr.zip' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'experiment.xenium' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cell_feature_matrix.zarr.zip' }).exists() }, + { assert process.out.outs != null }, + { assert file(process.out.outs.get(0).get(1)).isDirectory() }, + { assert file(process.out.outs.get(0).get(1)).list().size() > 0 }, + { assert snapshot(process.out.versions_xeniumranger).match()}, ) } } test("xeniumranger import-segmentation stub") { options "-stub" + when { process { """ - input[0] = Channel.of([ - [id: "test_xeniumranger_import-segmentation"], - ]).combine(UNZIP.out.unzipped_archive.map { it[1] }) - input[1] = 0 - input[2] = [] - input[3] = UNZIP.out.unzipped_archive.map { it[1] } + "/cells.zarr.zip" - input[4] = [] - input[5] = [] - input[6] = [] + input[0] = UNZIP.out.unzipped_archive + .map { _, bundle -> + [ + [id: "test_xeniumranger_import-segmentation"], + bundle, + [], + [], + bundle + "/cells.zarr.zip", + [], + [] + ] + } """ } } diff --git a/modules/nf-core/xeniumranger/import-segmentation/tests/main.nf.test.snap b/modules/nf-core/xeniumranger/import-segmentation/tests/main.nf.test.snap index 1c312ae0f3ba..b0f079b96e1e 100644 --- a/modules/nf-core/xeniumranger/import-segmentation/tests/main.nf.test.snap +++ b/modules/nf-core/xeniumranger/import-segmentation/tests/main.nf.test.snap @@ -1,72 +1,19 @@ { - "xeniumranger import-segmentation": { + "xeniumranger import-segmentation nuclei": { "content": [ [ - "versions.yml:md5,d76e870d71abf94ed9ae972a08b83f63" - ], - [ - "dispersion.csv:md5,e8b1abb880ece8fb730ce34a15f958b4", - "features_selected.csv:md5,c5e32d69f001f938ed316d2108a21e00", - "cell_feature_matrix.h5:md5,96cb400f1b1dd6f8796daea0ad5c74e6", - "barcodes.tsv.gz:md5,04ea06796d6b28517c288904ca043582", - "features.tsv.gz:md5,7862242129681900a9cc4086dc83b62e", - "matrix.mtx.gz:md5,489f86fbd8d65d6b973bb9cc7c5a76f1", - "gene_panel.json:md5,8890dd5fd90706e751554ac3fdfdedde", - "morphology.ome.tif:md5,6b65fff28a38a001b8f25061737fbf9b", - "morphology_focus_0000.ome.tif:md5,90e796ad634d14e62cf2ebcadf2eaf98" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-30T00:13:13.575888" - }, - "xeniumranger import-segmentation nuclei npy": { - "content": [ - [ - "versions.yml:md5,d76e870d71abf94ed9ae972a08b83f63" - ], - [ - "dispersion.csv:md5,e8b1abb880ece8fb730ce34a15f958b4", - "features_selected.csv:md5,c5e32d69f001f938ed316d2108a21e00", - "cell_feature_matrix.h5:md5,96cb400f1b1dd6f8796daea0ad5c74e6", - "barcodes.tsv.gz:md5,04ea06796d6b28517c288904ca043582", - "features.tsv.gz:md5,7862242129681900a9cc4086dc83b62e", - "matrix.mtx.gz:md5,489f86fbd8d65d6b973bb9cc7c5a76f1", - "gene_panel.json:md5,8890dd5fd90706e751554ac3fdfdedde", - "morphology.ome.tif:md5,6b65fff28a38a001b8f25061737fbf9b", - "morphology_focus_0000.ome.tif:md5,90e796ad634d14e62cf2ebcadf2eaf98" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-29T23:03:26.726334" - }, - "xeniumranger import-segmentation segmentation csv": { - "content": [ - [ - "versions.yml:md5,d76e870d71abf94ed9ae972a08b83f63" - ], - [ - "dispersion.csv:md5,e8b1abb880ece8fb730ce34a15f958b4", - "features_selected.csv:md5,c5e32d69f001f938ed316d2108a21e00", - "cell_feature_matrix.h5:md5,5d74ea595561e0300b6c3e5ec8d06fff", - "barcodes.tsv.gz:md5,97496a9b448d9380cff0575b8e7a6f57", - "features.tsv.gz:md5,7862242129681900a9cc4086dc83b62e", - "matrix.mtx.gz:md5,f93ed82a2a74c154392fc6237642f1d2", - "gene_panel.json:md5,8890dd5fd90706e751554ac3fdfdedde", - "morphology.ome.tif:md5,6b65fff28a38a001b8f25061737fbf9b", - "morphology_focus_0000.ome.tif:md5,90e796ad634d14e62cf2ebcadf2eaf98" + [ + "XENIUMRANGER_IMPORT_SEGMENTATION", + "xeniumranger", + "4.0.1.1" + ] ] ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2024-10-29T23:22:58.158857" + "timestamp": "2025-12-10T19:58:12.844137213" }, "xeniumranger import-segmentation stub": { "content": [ @@ -76,52 +23,41 @@ { "id": "test_xeniumranger_import-segmentation" }, - "fake_file.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "experiment.xenium:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], "1": [ - "versions.yml:md5,d76e870d71abf94ed9ae972a08b83f63" + [ + "XENIUMRANGER_IMPORT_SEGMENTATION", + "xeniumranger", + "4.0.1.1" + ] ], "outs": [ [ { "id": "test_xeniumranger_import-segmentation" }, - "fake_file.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "experiment.xenium:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], - "versions": [ - "versions.yml:md5,d76e870d71abf94ed9ae972a08b83f63" + "versions_xeniumranger": [ + [ + "XENIUMRANGER_IMPORT_SEGMENTATION", + "xeniumranger", + "4.0.1.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-30T22:49:39.204133" - }, - "xeniumranger import-segmentation nuclei tif": { - "content": [ - [ - "versions.yml:md5,d76e870d71abf94ed9ae972a08b83f63" - ], - [ - "dispersion.csv:md5,e8b1abb880ece8fb730ce34a15f958b4", - "features_selected.csv:md5,c5e32d69f001f938ed316d2108a21e00", - "cell_feature_matrix.h5:md5,96cb400f1b1dd6f8796daea0ad5c74e6", - "barcodes.tsv.gz:md5,04ea06796d6b28517c288904ca043582", - "features.tsv.gz:md5,7862242129681900a9cc4086dc83b62e", - "matrix.mtx.gz:md5,489f86fbd8d65d6b973bb9cc7c5a76f1", - "gene_panel.json:md5,8890dd5fd90706e751554ac3fdfdedde", - "morphology.ome.tif:md5,6b65fff28a38a001b8f25061737fbf9b", - "morphology_focus_0000.ome.tif:md5,90e796ad634d14e62cf2ebcadf2eaf98" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2024-10-29T23:11:37.18721" + "timestamp": "2025-12-10T19:58:19.883560548" } } \ No newline at end of file diff --git a/modules/nf-core/xeniumranger/import-segmentation/tests/nextflow.config b/modules/nf-core/xeniumranger/import-segmentation/tests/nextflow.config deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/modules/nf-core/xeniumranger/relabel/main.nf b/modules/nf-core/xeniumranger/relabel/main.nf index b06fe9ea13eb..bf04a9713ec6 100644 --- a/modules/nf-core/xeniumranger/relabel/main.nf +++ b/modules/nf-core/xeniumranger/relabel/main.nf @@ -2,55 +2,46 @@ process XENIUMRANGER_RELABEL { tag "$meta.id" label 'process_high' - container "nf-core/xeniumranger:3.0.1" + container "nf-core/xeniumranger:4.0" input: - tuple val(meta), path(xenium_bundle) - path(gene_panel) + tuple val(meta), path(xenium_bundle, stageAs: "bundle/"), path(panel) output: - tuple val(meta), path("**/outs/**"), emit: outs - path "versions.yml", emit: versions + tuple val(meta), path("${prefix}"), emit: outs + tuple val("${task.process}"), val("xeniumranger"), eval("xeniumranger -V | sed -e 's/.*xenium-//'"), emit: versions_xeniumranger, topic: versions when: task.ext.when == null || task.ext.when script: + // Exit if running this module with -profile conda / -profile mamba if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { error "XENIUMRANGER_RELABEL module does not support Conda. Please use Docker / Singularity / Podman instead." } - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + + prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: "" """ xeniumranger relabel \\ - --id="${prefix}" \\ + --id="XENIUMRANGER_RELABEL" \\ --xenium-bundle="${xenium_bundle}" \\ - --panel="${gene_panel}" \\ + --panel="${panel}" \\ --localcores=${task.cpus} \\ --localmem=${task.memory.toGiga()} \\ ${args} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - xeniumranger: \$(xeniumranger -V | sed -e "s/xeniumranger-/- /g") - END_VERSIONS + rm -rf "${prefix}" + mv XENIUMRANGER_RELABEL/outs "${prefix}" """ stub: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "XENIUMRANGER_RELABEL module does not support Conda. Please use Docker / Singularity / Podman instead." - } - def prefix = task.ext.prefix ?: "${meta.id}" - """ - mkdir -p "${prefix}/outs/" - touch "${prefix}/outs/fake_file.txt" + prefix = task.ext.prefix ?: "${meta.id}" - cat <<-END_VERSIONS > versions.yml - "${task.process}": - xeniumranger: \$(xeniumranger -V | sed -e "s/xeniumranger-/- /g") - END_VERSIONS + """ + mkdir -p "${prefix}" + touch "${prefix}/experiment.xenium" """ } diff --git a/modules/nf-core/xeniumranger/relabel/meta.yml b/modules/nf-core/xeniumranger/relabel/meta.yml index 1d4d263bf214..8b61e0bb8f02 100644 --- a/modules/nf-core/xeniumranger/relabel/meta.yml +++ b/modules/nf-core/xeniumranger/relabel/meta.yml @@ -1,6 +1,6 @@ name: xeniumranger_relabel -description: The xeniumranger relabel module allows you to change the gene labels - applied to decoded transcripts. +description: The xeniumranger relabel module allows you to change the gene + labels applied to decoded transcripts. keywords: - spatial - relabel @@ -15,44 +15,58 @@ tools: documentation: "https://www.10xgenomics.com/support/software/xenium-ranger/latest/getting-started" tool_dev_url: "https://www.10xgenomics.com/support/software/xenium-ranger/latest/analysis" licence: - - 10x Genomics EULA + - "10x Genomics EULA" identifier: "" input: - - meta: type: map description: | Groovy Map containing run information - e.g. [id:'xenium_bundle_path'] + e.g. [ id:'xenium_bundle_path' ] - xenium_bundle: type: directory - description: Path to the xenium output bundle generated by the Xenium Onboard - Analysis pipeline - - gene_panel: - type: file - description: Gene panel JSON file to use for relabeling decoded transcripts - ontologies: [] + description: Path to the xenium output bundle generated by the Xenium + Onboard Analysis pipeline + - panel: + type: file + description: Path to the gene panel file + pattern: "*.json" + ontologies: + - edam: http://edamontology.org/format_3464 # JSON output: outs: - - meta: - type: file - description: Files containing the outputs of Cell Ranger, see official 10X - Genomics documentation for a complete list - pattern: "${meta.id}/outs/*" - ontologies: [] - - "**/outs/**": - type: file - description: Files containing the outputs of xenium ranger, see official 10X - Genomics documentation for a complete list of outputs - pattern: "${meta.id}/outs/*" - ontologies: [] + type: map + description: Groovy Map containing sample information e.g. [ id:'test' ] + - "${prefix}": + type: directory + description: Directory containing the output xenium bundle of Xenium + Ranger + pattern: "${prefix}" + versions_xeniumranger: + - - "${task.process}": + type: string + description: The process the versions were collected from + - xeniumranger: + type: string + description: The tool name + - "xeniumranger -V | sed -e 's/.*xenium-//'": + type: string + description: The command used to generate the version of the tool +topics: versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - - "${task.process}": + type: string + description: The process the versions were collected from + - xeniumranger: + type: string + description: The tool name + - "xeniumranger -V | sed -e 's/.*xenium-//'": + type: string + description: The command used to generate the version of the tool authors: - "@khersameesh24" + - "@dongzehe" maintainers: - "@khersameesh24" + - "@dongzehe" diff --git a/modules/nf-core/xeniumranger/relabel/tests/main.nf.test b/modules/nf-core/xeniumranger/relabel/tests/main.nf.test index 9db6e96a62f1..6518e8b8214d 100644 --- a/modules/nf-core/xeniumranger/relabel/tests/main.nf.test +++ b/modules/nf-core/xeniumranger/relabel/tests/main.nf.test @@ -3,7 +3,6 @@ nextflow_process { name "Test Process XENIUMRANGER_RELABEL" script "../main.nf" process "XENIUMRANGER_RELABEL" - config "./nextflow.config" tag "modules" tag "modules_nfcore" @@ -11,25 +10,31 @@ nextflow_process { tag "xeniumranger/relabel" tag "unzip" + setup { - run("UNZIP") { - script "modules/nf-core/unzip/main.nf" - process { - """ - input[0] = [[], file('https://raw.githubusercontent.com/nf-core/test-datasets/spatialxe/Xenium_Prime_Mouse_Ileum_tiny_outs.zip', checkIfExists: true)] - """ - } + + run("UNZIP") { + script "modules/nf-core/unzip/main.nf" + process { + """ + input[0] = [[], file('https://raw.githubusercontent.com/nf-core/test-datasets/spatialxe/Xenium_V1_Protein_Human_Kidney_tiny_outs.zip', checkIfExists: true)] + """ } + } } test("xeniumranger relabel") { when { process { """ - input[0] = Channel.of([ - [id: "test_xeniumranger_relabel"], - ]).combine(UNZIP.out.unzipped_archive.map { it[1] }) - input[1] = UNZIP.out.unzipped_archive.map { it[1] } + "/gene_panel.json" + input[0] = UNZIP.out.unzipped_archive + .map { _, bundle -> + [ + [id: "test_xeniumranger_relabel"], + bundle, + bundle + "/gene_panel.json" + ] + } """ } } @@ -37,37 +42,10 @@ nextflow_process { assertAll( { assert process.success }, { assert process.out.outs != null }, - { - assert snapshot( - process.out.versions, - process.out.outs.get(0).get(1).findAll { file(it).name !in [ - "analysis.zarr.zip", - "experiment.xenium", - "transcripts.zarr.zip", - "analysis_summary.html", - "cell_feature_matrix.zarr.zip", - "differential_expression.csv", - "components.csv", - "projection.csv", - "variance.csv", - "metrics_summary.csv", - "clusters.csv" - ]} - ).match() - }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'analysis_summary.html' }).exists() }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'analysis.zarr.zip' }).exists() }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'experiment.xenium' }).exists() }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'transcripts.zarr.zip' }).exists() }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'analysis_summary.html' }).exists() }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'cell_feature_matrix.zarr.zip' }).exists() }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'differential_expression.csv' }).exists() }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'components.csv' }).exists() }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'projection.csv' }).exists() }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'variance.csv' }).exists() }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'metrics_summary.csv' }).exists() }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'clusters.csv' }).exists() }, - ) + { assert file(process.out.outs.get(0).get(1)).isDirectory() }, + { assert file(process.out.outs.get(0).get(1)).list().size() > 0 }, + { assert snapshot(process.out.versions_xeniumranger).match()}, + ) } } @@ -76,10 +54,14 @@ nextflow_process { when { process { """ - input[0] = Channel.of([ - [id: "test_xeniumranger_relabel"], - ]).combine(UNZIP.out.unzipped_archive.map { it[1] }) - input[1] = UNZIP.out.unzipped_archive.map { it[1] } + "/gene_panel.json" + input[0] = UNZIP.out.unzipped_archive + .map { _, bundle -> + [ + [id: "test_xeniumranger_relabel"], + bundle, + bundle + "/gene_panel.json" + ] + } """ } } diff --git a/modules/nf-core/xeniumranger/relabel/tests/main.nf.test.snap b/modules/nf-core/xeniumranger/relabel/tests/main.nf.test.snap index 7c70cfc28faa..63af4ff31a16 100644 --- a/modules/nf-core/xeniumranger/relabel/tests/main.nf.test.snap +++ b/modules/nf-core/xeniumranger/relabel/tests/main.nf.test.snap @@ -2,33 +2,18 @@ "xeniumranger relabel": { "content": [ [ - "versions.yml:md5,ab2584177544560d5a9e9c36f7d24354" - ], - [ - "dispersion.csv:md5,e8b1abb880ece8fb730ce34a15f958b4", - "features_selected.csv:md5,c5e32d69f001f938ed316d2108a21e00", - "cell_boundaries.csv.gz:md5,8b4f2aa455a6fb14b2669a42db32ea7e", - "cell_boundaries.parquet:md5,e55d6a7fbec336103994baad8c8e4a9a", - "cell_feature_matrix.h5:md5,96cb400f1b1dd6f8796daea0ad5c74e6", - "barcodes.tsv.gz:md5,04ea06796d6b28517c288904ca043582", - "features.tsv.gz:md5,7862242129681900a9cc4086dc83b62e", - "matrix.mtx.gz:md5,489f86fbd8d65d6b973bb9cc7c5a76f1", - "cells.csv.gz:md5,3cef2d7cc8cfba1d47bdb7c65c3d5d5f", - "cells.parquet:md5,9b30b35ab961d2d243a1426e8dc980fe", - "cells.zarr.zip:md5,556e47d5b14150239b10b2f801defa2b", - "gene_panel.json:md5,8890dd5fd90706e751554ac3fdfdedde", - "morphology.ome.tif:md5,6b65fff28a38a001b8f25061737fbf9b", - "morphology_focus_0000.ome.tif:md5,90e796ad634d14e62cf2ebcadf2eaf98", - "nucleus_boundaries.csv.gz:md5,e417b6e293298870956d42c7106cbd0c", - "nucleus_boundaries.parquet:md5,bacbfc3c2e956d899e1d8ccba5dd7c5e", - "transcripts.parquet:md5,c0f40d5c61b87404bc9efb84ff0563a8" + [ + "XENIUMRANGER_RELABEL", + "xeniumranger", + "4.0.1.1" + ] ] ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2024-10-29T21:06:09.082129" + "timestamp": "2025-12-10T20:00:59.571728235" }, "xeniumranger relabel stub": { "content": [ @@ -38,29 +23,41 @@ { "id": "test_xeniumranger_relabel" }, - "fake_file.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "experiment.xenium:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], "1": [ - "versions.yml:md5,ab2584177544560d5a9e9c36f7d24354" + [ + "XENIUMRANGER_RELABEL", + "xeniumranger", + "4.0.1.1" + ] ], "outs": [ [ { "id": "test_xeniumranger_relabel" }, - "fake_file.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "experiment.xenium:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], - "versions": [ - "versions.yml:md5,ab2584177544560d5a9e9c36f7d24354" + "versions_xeniumranger": [ + [ + "XENIUMRANGER_RELABEL", + "xeniumranger", + "4.0.1.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2024-10-22T15:22:34.353444" + "timestamp": "2025-12-10T20:01:06.673047685" } } \ No newline at end of file diff --git a/modules/nf-core/xeniumranger/relabel/tests/nextflow.config b/modules/nf-core/xeniumranger/relabel/tests/nextflow.config deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/modules/nf-core/xeniumranger/rename/main.nf b/modules/nf-core/xeniumranger/rename/main.nf index d273caf3276c..dc653daed371 100644 --- a/modules/nf-core/xeniumranger/rename/main.nf +++ b/modules/nf-core/xeniumranger/rename/main.nf @@ -2,31 +2,33 @@ process XENIUMRANGER_RENAME { tag "$meta.id" label 'process_high' - container "nf-core/xeniumranger:3.0.1" + container "nf-core/xeniumranger:4.0" input: - tuple val(meta), path(xenium_bundle) - val(region_name) - val(cassette_name) + tuple val(meta), path(xenium_bundle, stageAs: "bundle/"), val(region_name), val(cassette_name) output: - tuple val(meta), path("**/outs/**"), emit: outs - path "versions.yml", emit: versions + tuple val(meta), path("${prefix}"), emit: outs + tuple val("${task.process}"), val("xeniumranger"), eval("xeniumranger -V | sed -e 's/.*xenium-//'"), emit: versions_xeniumranger, topic: versions when: task.ext.when == null || task.ext.when script: + // Exit if running this module with -profile conda / -profile mamba if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { error "XENIUMRANGER_RENAME module does not support Conda. Please use Docker / Singularity / Podman instead." } - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + + def args = task.ext.args ?: "" + prefix = task.ext.prefix ?: "${meta.id}" """ + rm -rf "${prefix}" + xeniumranger rename \\ - --id="${prefix}" \\ + --id="XENIUMRANGER_RENAME" \\ --xenium-bundle="${xenium_bundle}" \\ --region-name="${region_name}" \\ --cassette-name="${cassette_name}" \\ @@ -34,25 +36,15 @@ process XENIUMRANGER_RENAME { --localmem=${task.memory.toGiga()} \\ ${args} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - xeniumranger: \$(xeniumranger -V | sed -e "s/xeniumranger-/- /g") - END_VERSIONS + mv XENIUMRANGER_RENAME/outs "${prefix}" """ stub: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "XENIUMRANGER_RENAME module does not support Conda. Please use Docker / Singularity / Podman instead." - } - def prefix = task.ext.prefix ?: "${meta.id}" - """ - mkdir -p "${prefix}/outs/" - touch "${prefix}/outs/fake_file.txt" - cat <<-END_VERSIONS > versions.yml - "${task.process}": - xeniumranger: \$(xeniumranger -V | sed -e "s/xeniumranger-/- /g") - END_VERSIONS + prefix = task.ext.prefix ?: "${meta.id}" + + """ + mkdir -p "${prefix}" + touch "${prefix}/experiment.xenium" """ } diff --git a/modules/nf-core/xeniumranger/rename/meta.yml b/modules/nf-core/xeniumranger/rename/meta.yml index 30b79d922fe5..b3880f4ec268 100644 --- a/modules/nf-core/xeniumranger/rename/meta.yml +++ b/modules/nf-core/xeniumranger/rename/meta.yml @@ -1,7 +1,7 @@ name: xeniumranger_rename -description: The xeniumranger rename module allows you to change the sample region_name - and cassette_name throughout all the Xenium Onboard Analysis output files that contain - this information. +description: The xeniumranger rename module allows you to change the sample + region_name and cassette_name throughout all the Xenium Onboard Analysis + output files that contain this information. keywords: - spatial - rename @@ -24,36 +24,48 @@ input: description: Groovy Map containing sample information e.g. [ id:'test' ] - xenium_bundle: type: directory - description: Path to the xenium output bundle generated by the Xenium Onboard - Analysis pipeline - - region_name: - type: string - description: New region name - - cassette_name: - type: string - description: New cassette name + description: Path to the xenium output bundle generated by the Xenium + Onboard Analysis pipeline + - region_name: + type: string + description: New region name + - cassette_name: + type: string + description: New cassette name output: outs: - - meta: - type: file - description: Files containing the outputs of Cell Ranger, see official 10X - Genomics documentation for a complete list - pattern: "${meta.id}/outs/*" - ontologies: [] - - "**/outs/**": - type: file - description: Files containing the outputs of xenium ranger, see official 10X - Genomics documentation for a complete list of outputs - pattern: "${meta.id}/outs/*" - ontologies: [] + type: map + description: Groovy Map containing sample information e.g. [ id:'test' ] + - "${prefix}": + type: directory + description: Directory containing the output xenium bundle of Xenium + Ranger + pattern: "${prefix}" + versions_xeniumranger: + - - "${task.process}": + type: string + description: The process the versions were collected from + - xeniumranger: + type: string + description: The tool name + - "xeniumranger -V | sed -e 's/.*xenium-//'": + type: string + description: The command used to generate the version of the tool +topics: versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - - "${task.process}": + type: string + description: The process the versions were collected from + - xeniumranger: + type: string + description: The tool name + - "xeniumranger -V | sed -e 's/.*xenium-//'": + type: string + description: The command used to generate the version of the tool authors: - "@khersameesh24" + - "@dongzehe" maintainers: - "@khersameesh24" + - "@dongzehe" diff --git a/modules/nf-core/xeniumranger/rename/tests/main.nf.test b/modules/nf-core/xeniumranger/rename/tests/main.nf.test index 36bf00d95d30..07b1eaeb8b20 100644 --- a/modules/nf-core/xeniumranger/rename/tests/main.nf.test +++ b/modules/nf-core/xeniumranger/rename/tests/main.nf.test @@ -3,7 +3,6 @@ nextflow_process { name "Test Process XENIUMRANGER_RENAME" script "../main.nf" process "XENIUMRANGER_RENAME" - config "./nextflow.config" tag "modules" tag "modules_nfcore" @@ -16,7 +15,7 @@ nextflow_process { script "modules/nf-core/unzip/main.nf" process { """ - input[0] = [[], file('https://raw.githubusercontent.com/nf-core/test-datasets/spatialxe/Xenium_Prime_Mouse_Ileum_tiny_outs.zip', checkIfExists: true)] + input[0] = [[], file('https://raw.githubusercontent.com/nf-core/test-datasets/spatialxe/Xenium_V1_Protein_Human_Kidney_tiny_outs.zip', checkIfExists: true)] """ } } @@ -26,11 +25,15 @@ nextflow_process { when { process { """ - input[0] = Channel.of([ + input[0] = UNZIP.out.unzipped_archive + .map { _, bundle -> + [ [id: "test_xeniumranger_rename"], - ]).combine(UNZIP.out.unzipped_archive.map { it[1] }) - input[1] = "test_region" - input[2] = "test_cassette" + bundle, + "test_region", + "test_cassette" + ] + } """ } } @@ -38,18 +41,16 @@ nextflow_process { assertAll( { assert process.success }, { assert process.out.outs != null }, - { - assert snapshot( - process.out.versions, - process.out.outs.get(0).get(1).findAll { file(it).name !in [ - 'analysis_summary.html', - 'experiment.xenium', - ]} - ).match() - }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'analysis_summary.html' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'experiment.xenium' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'metrics_summary.csv' }).exists() } + { assert file(process.out.outs.get(0).get(1)).isDirectory() }, + { assert file(process.out.outs.get(0).get(1) + "/analysis_summary.html").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/cells.csv.gz").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/cells.parquet").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/cells.zarr.zip").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/transcripts.parquet").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/transcripts.zarr.zip").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/analysis.zarr.zip").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/cell_feature_matrix.zarr.zip").exists() }, + { assert snapshot(process.out.versions_xeniumranger).match()}, ) } } @@ -59,11 +60,15 @@ nextflow_process { when { process { """ - input[0] = Channel.of([ + input[0] = UNZIP.out.unzipped_archive + .map { meta, bundle -> + [ [id: "test_xeniumranger_rename"], - ]).combine(UNZIP.out.unzipped_archive.map { it[1] }) - input[1] = "test_region" - input[2] = "test_cassette" + bundle, + "test_region", + "test_cassette" + ] + } """ } } diff --git a/modules/nf-core/xeniumranger/rename/tests/main.nf.test.snap b/modules/nf-core/xeniumranger/rename/tests/main.nf.test.snap index ea57ab7e0fd6..5127d1cc25ff 100644 --- a/modules/nf-core/xeniumranger/rename/tests/main.nf.test.snap +++ b/modules/nf-core/xeniumranger/rename/tests/main.nf.test.snap @@ -1,4 +1,20 @@ { + "xeniumranger rename": { + "content": [ + [ + [ + "XENIUMRANGER_RENAME", + "xeniumranger", + "4.0.1.1" + ] + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-10T20:01:21.033622706" + }, "xeniumranger rename stub": { "content": [ { @@ -7,59 +23,41 @@ { "id": "test_xeniumranger_rename" }, - "fake_file.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "experiment.xenium:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], "1": [ - "versions.yml:md5,823917e7bc8f27cf314ef477fe7369eb" + [ + "XENIUMRANGER_RENAME", + "xeniumranger", + "4.0.1.1" + ] ], "outs": [ [ { "id": "test_xeniumranger_rename" }, - "fake_file.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "experiment.xenium:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], - "versions": [ - "versions.yml:md5,823917e7bc8f27cf314ef477fe7369eb" + "versions_xeniumranger": [ + [ + "XENIUMRANGER_RENAME", + "xeniumranger", + "4.0.1.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-30T23:10:43.918492" - }, - "xeniumranger rename": { - "content": [ - [ - "versions.yml:md5,823917e7bc8f27cf314ef477fe7369eb" - ], - [ - "analysis.zarr.zip:md5,1ffb1b86586fe6c80ce1676b79137785", - "cell_boundaries.csv.gz:md5,8b4f2aa455a6fb14b2669a42db32ea7e", - "cell_boundaries.parquet:md5,e55d6a7fbec336103994baad8c8e4a9a", - "cell_feature_matrix.h5:md5,96cb400f1b1dd6f8796daea0ad5c74e6", - "cell_feature_matrix.zarr.zip:md5,36f45a290cf4ee1232f2d1cd0fdbd820", - "cells.csv.gz:md5,3cef2d7cc8cfba1d47bdb7c65c3d5d5f", - "cells.parquet:md5,e1450c7eca3d7ce0d4911c95042b1303", - "cells.zarr.zip:md5,556e47d5b14150239b10b2f801defa2b", - "gene_panel.json:md5,8890dd5fd90706e751554ac3fdfdedde", - "metrics_summary.csv:md5,54ad3944eb3ba6a4d7bda01bc2a6bb1c", - "morphology.ome.tif:md5,6b65fff28a38a001b8f25061737fbf9b", - "morphology_focus_0000.ome.tif:md5,90e796ad634d14e62cf2ebcadf2eaf98", - "nucleus_boundaries.csv.gz:md5,e417b6e293298870956d42c7106cbd0c", - "nucleus_boundaries.parquet:md5,bacbfc3c2e956d899e1d8ccba5dd7c5e", - "transcripts.parquet:md5,203cb05ee7689805cc505ebda9557551", - "transcripts.zarr.zip:md5,807e63a2ef8340e085cd899507f45395" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2024-10-30T23:10:34.499597" + "timestamp": "2025-12-10T20:01:28.086802143" } -} \ No newline at end of file +} diff --git a/modules/nf-core/xeniumranger/rename/tests/nextflow.config b/modules/nf-core/xeniumranger/rename/tests/nextflow.config deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/modules/nf-core/xeniumranger/resegment/main.nf b/modules/nf-core/xeniumranger/resegment/main.nf index 5d28fa698a76..d52eba0e9e83 100644 --- a/modules/nf-core/xeniumranger/resegment/main.nf +++ b/modules/nf-core/xeniumranger/resegment/main.nf @@ -2,69 +2,44 @@ process XENIUMRANGER_RESEGMENT { tag "$meta.id" label 'process_high' - container "nf-core/xeniumranger:3.0.1" + container "nf-core/xeniumranger:4.0" input: - tuple val(meta), path(xenium_bundle) - val(expansion_distance) - val(dapi_filter) - val(boundary_stain) - val(interior_stain) + tuple val(meta), path(xenium_bundle, stageAs: "bundle/") output: - tuple val(meta), path("**/outs/**"), emit: outs - path "versions.yml", emit: versions + tuple val(meta), path("${prefix}"), emit: outs + tuple val("${task.process}"), val("xeniumranger"), eval("xeniumranger -V | sed -e 's/.*xenium-//'"), emit: versions_xeniumranger, topic: versions when: task.ext.when == null || task.ext.when script: + // Exit if running this module with -profile conda / -profile mamba if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { error "XENIUMRANGER_RESEGMENT module does not support Conda. Please use Docker / Singularity / Podman instead." } - def args = task.ext.args ?: "" - def prefix = task.ext.prefix ?: "${meta.id}" - - def expansion_distance = expansion_distance ? "--expansion-distance=\"${expansion_distance}\"": "" - def dapi_filter = dapi_filter ? "--dapi-filter=\"${dapi_filter}\"": "" - // Do not use boundary stain in analysis, but keep default interior stain and DAPI - def boundary_stain = boundary_stain ? "--boundary-stain=disable": "" - // Do not use interior stain in analysis, but keep default boundary stain and DAPI - def interior_stain = interior_stain ? "--interior-stain=disable": "" + prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: "" """ xeniumranger resegment \\ - --id="${prefix}" \\ + --id="XENIUMRANGER_RESEGMENT" \\ --xenium-bundle="${xenium_bundle}" \\ - ${expansion_distance} \\ - ${dapi_filter} \\ - ${boundary_stain} \\ - ${interior_stain} \\ --localcores=${task.cpus} \\ --localmem=${task.memory.toGiga()} \\ ${args} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - xeniumranger: \$(xeniumranger -V | sed -e "s/xeniumranger-/- /g") - END_VERSIONS + rm -rf "${prefix}" + mv XENIUMRANGER_RESEGMENT/outs "${prefix}" """ stub: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "XENIUMRANGER_RESEGMENT module does not support Conda. Please use Docker / Singularity / Podman instead." - } - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" """ - mkdir -p "${prefix}/outs/" - touch "${prefix}/outs/fake_file.txt" - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - xeniumranger: \$(xeniumranger -V | sed -e "s/xeniumranger-/- /g") - END_VERSIONS + mkdir -p "${prefix}" + touch "${prefix}/experiment.xenium" """ } diff --git a/modules/nf-core/xeniumranger/resegment/meta.yml b/modules/nf-core/xeniumranger/resegment/meta.yml index 6666134916a8..687c67231830 100644 --- a/modules/nf-core/xeniumranger/resegment/meta.yml +++ b/modules/nf-core/xeniumranger/resegment/meta.yml @@ -1,7 +1,7 @@ name: xeniumranger_resegment -description: The xeniumranger resegment module allows you to generate a new segmentation - of the morphology image space by rerunning the Xenium Onboard Analysis (XOA) segmentation - algorithms with modified parameters. +description: The xeniumranger resegment module allows you to generate a new + segmentation of the morphology image space by rerunning the Xenium Onboard + Analysis (XOA) segmentation algorithms with modified parameters. keywords: - spatial - resegment @@ -26,47 +26,44 @@ input: e.g. [ id:'xenium_experiment' ] - xenium_bundle: type: directory - description: Path to the xenium output bundle generated by the Xenium Onboard - Analysis pipeline - - expansion_distance: - type: integer - description: Nuclei boundary expansion distance in µm. Only for use when nucleus - segmentation provided as input. Default-5 (accepted range 0 - 100) - - dapi_filter: - type: integer - description: Minimum intensity in photoelectrons to filter nuclei default-100 - range of values is 0 to 99th percentile of image stack or 1000, whichever is - larger - - boundary_stain: - type: string - description: Specify the name of the boundary stain to use or disable possible - options are default-ATP1A1/CD45/E-Cadherin or disable - - interior_stain: - type: string - description: Specify the name of the interior stain to use or disable possible - options are default-18S or disable + description: Path to the xenium output bundle generated by the Xenium + Onboard Analysis pipeline output: outs: - - meta: - type: file - description: Files containing the outputs of Cell Ranger, see official 10X - Genomics documentation for a complete list - pattern: "${meta.id}/outs/*" - ontologies: [] - - "**/outs/**": - type: file - description: Files containing the outputs of xenium ranger, see official 10X - Genomics documentation for a complete list of outputs - pattern: "${meta.id}/outs/*" - ontologies: [] + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - "${prefix}": + type: directory + description: Directory containing the output xenium bundle of Xenium + Ranger + pattern: "${prefix}" + versions_xeniumranger: + - - "${task.process}": + type: string + description: The process the versions were collected from + - xeniumranger: + type: string + description: The tool name + - "xeniumranger -V | sed -e 's/.*xenium-//'": + type: string + description: The command used to generate the version of the tool +topics: versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - - "${task.process}": + type: string + description: The process the versions were collected from + - xeniumranger: + type: string + description: The tool name + - "xeniumranger -V | sed -e 's/.*xenium-//'": + type: string + description: The command used to generate the version of the tool authors: - "@khersameesh24" + - "@dongzehe" maintainers: - "@khersameesh24" + - "@dongzehe" diff --git a/modules/nf-core/xeniumranger/resegment/tests/main.nf.test b/modules/nf-core/xeniumranger/resegment/tests/main.nf.test index 85fc63e580c2..c24d897d72e2 100644 --- a/modules/nf-core/xeniumranger/resegment/tests/main.nf.test +++ b/modules/nf-core/xeniumranger/resegment/tests/main.nf.test @@ -3,7 +3,6 @@ nextflow_process { name "Test Process XENIUMRANGER_RESEGMENT" script "../main.nf" process "XENIUMRANGER_RESEGMENT" - config "./nextflow.config" tag "modules" tag "modules_nfcore" @@ -12,42 +11,45 @@ nextflow_process { tag "unzip" setup { - run("UNZIP") { - script "modules/nf-core/unzip/main.nf" - process { - """ - input[0] = [[], file('https://raw.githubusercontent.com/nf-core/test-datasets/spatialxe/Xenium_Prime_Mouse_Ileum_tiny_outs.zip', checkIfExists: true)] - """ - } + run("UNZIP") { + script "modules/nf-core/unzip/main.nf" + process { + """ + input[0] = [[], file('https://raw.githubusercontent.com/nf-core/test-datasets/spatialxe/Xenium_V1_Protein_Human_Kidney_tiny_outs.zip', checkIfExists: true)] + """ } + } } test("xeniumranger resegment") { when { process { """ - input[0] = Channel.of([ - [id: "test_xeniumranger_resegment"], - ]).combine(UNZIP.out.unzipped_archive.map { it[1] }) - input[1] = [] - input[2] = [] - input[3] = [] - input[4] = [] + input[0] = UNZIP.out.unzipped_archive.map { + _, bundle -> + [ + [id: "test_xeniumranger_resegment"], + bundle + ] + } """ } } then { + // xeniumranger doesn't generate deterministic outputs, so we can't use snapshot assertAll( { assert process.success }, { assert process.out.outs != null }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'analysis_summary.html' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.csv.gz' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'cells.zarr.zip' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'transcripts.parquet' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'transcripts.zarr.zip' }).exists() }, - { assert file(process.out.outs.get(0).get(1).find { file(it).name == 'analysis.zarr.zip' }).exists() }, - { assert path(process.out.outs.get(0).get(1).find { file(it).name == 'cell_feature_matrix.zarr.zip' }).exists() } + { assert file(process.out.outs.get(0).get(1)).isDirectory() }, + { assert file(process.out.outs.get(0).get(1) + "/analysis_summary.html").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/cells.csv.gz").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/cells.parquet").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/cells.zarr.zip").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/transcripts.parquet").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/transcripts.zarr.zip").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/analysis.zarr.zip").exists() }, + { assert file(process.out.outs.get(0).get(1) + "/cell_feature_matrix.zarr.zip").exists()}, + { assert snapshot(process.out.versions_xeniumranger).match()}, ) } } @@ -57,13 +59,13 @@ nextflow_process { when { process { """ - input[0] = Channel.of([ - [id: "test_xeniumranger_resegment"], - ]).combine(UNZIP.out.unzipped_archive.map { it[1] }) - input[1] = [] - input[2] = [] - input[3] = [] - input[4] = [] + input[0] = UNZIP.out.unzipped_archive.map { + _, bundle -> + [ + [id: "test_xeniumranger_resegment"], + bundle + ] + } """ } } diff --git a/modules/nf-core/xeniumranger/resegment/tests/main.nf.test.snap b/modules/nf-core/xeniumranger/resegment/tests/main.nf.test.snap index 16f94c14ebf2..cbeaa885f6dd 100644 --- a/modules/nf-core/xeniumranger/resegment/tests/main.nf.test.snap +++ b/modules/nf-core/xeniumranger/resegment/tests/main.nf.test.snap @@ -1,4 +1,20 @@ { + "xeniumranger resegment": { + "content": [ + [ + [ + "XENIUMRANGER_RESEGMENT", + "xeniumranger", + "4.0.1.1" + ] + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-12-10T21:21:39.73207635" + }, "xeniumranger resegment stub": { "content": [ { @@ -7,29 +23,41 @@ { "id": "test_xeniumranger_resegment" }, - "fake_file.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "experiment.xenium:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], "1": [ - "versions.yml:md5,4671141281357e0ce26d9cb35fed23a8" + [ + "XENIUMRANGER_RESEGMENT", + "xeniumranger", + "4.0.1.1" + ] ], "outs": [ [ { "id": "test_xeniumranger_resegment" }, - "fake_file.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "experiment.xenium:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], - "versions": [ - "versions.yml:md5,4671141281357e0ce26d9cb35fed23a8" + "versions_xeniumranger": [ + [ + "XENIUMRANGER_RESEGMENT", + "xeniumranger", + "4.0.1.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.2", + "nextflow": "25.04.6" }, - "timestamp": "2024-10-30T23:22:35.438329" + "timestamp": "2025-12-10T21:21:47.102042217" } -} \ No newline at end of file +} diff --git a/modules/nf-core/xeniumranger/resegment/tests/nextflow.config b/modules/nf-core/xeniumranger/resegment/tests/nextflow.config deleted file mode 100644 index e69de29bb2d1..000000000000 From 41ac4647971527723dbef3a685a424123711c9ad Mon Sep 17 00:00:00 2001 From: Jinn <155078830+jkh00@users.noreply.github.com> Date: Thu, 11 Dec 2025 10:48:48 +0100 Subject: [PATCH 62/83] Version update: Modkit repair, callmods and bedmethyltobigwig (#9547) * update to v0.6 * update to v0.6 * update to v0.6 * update yml * update to v0.6 * update snapshot * update snapshot --------- Co-authored-by: ra25wog --- .../modkit/bedmethyltobigwig/environment.yml | 2 +- .../nf-core/modkit/bedmethyltobigwig/main.nf | 4 +-- .../bedmethyltobigwig/tests/main.nf.test.snap | 30 +++++++++---------- .../nf-core/modkit/callmods/environment.yml | 2 +- modules/nf-core/modkit/callmods/main.nf | 4 +-- .../modkit/callmods/tests/main.nf.test.snap | 12 ++++---- modules/nf-core/modkit/repair/environment.yml | 2 +- modules/nf-core/modkit/repair/main.nf | 4 +-- modules/nf-core/modkit/repair/meta.yml | 3 +- .../modkit/repair/tests/main.nf.test.snap | 12 ++++---- 10 files changed, 37 insertions(+), 38 deletions(-) diff --git a/modules/nf-core/modkit/bedmethyltobigwig/environment.yml b/modules/nf-core/modkit/bedmethyltobigwig/environment.yml index 074604f01e3a..f4a14f4abb43 100644 --- a/modules/nf-core/modkit/bedmethyltobigwig/environment.yml +++ b/modules/nf-core/modkit/bedmethyltobigwig/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - "bioconda::ont-modkit=0.5.0" + - "bioconda::ont-modkit=0.6.0" diff --git a/modules/nf-core/modkit/bedmethyltobigwig/main.nf b/modules/nf-core/modkit/bedmethyltobigwig/main.nf index d51fb94e8a0f..dd0737d7dc2f 100644 --- a/modules/nf-core/modkit/bedmethyltobigwig/main.nf +++ b/modules/nf-core/modkit/bedmethyltobigwig/main.nf @@ -4,8 +4,8 @@ process MODKIT_BEDMETHYLTOBIGWIG { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/30/30413db983a1908edc096dcd8a31e7c26363b2010c5293e6bf59c0cef5d4a88a/data': - 'biocontainers/ont-modkit:0.5.0--hcdda2d0_1' }" + 'https://depot.galaxyproject.org/singularity/ont-modkit:0.6.0--hcdda2d0_0': + 'biocontainers/ont-modkit:0.6.0--hcdda2d0_0' }" input: tuple val(meta), path(bedmethyl) diff --git a/modules/nf-core/modkit/bedmethyltobigwig/tests/main.nf.test.snap b/modules/nf-core/modkit/bedmethyltobigwig/tests/main.nf.test.snap index 7fedc4e7d057..d3ebb75cfbcd 100644 --- a/modules/nf-core/modkit/bedmethyltobigwig/tests/main.nf.test.snap +++ b/modules/nf-core/modkit/bedmethyltobigwig/tests/main.nf.test.snap @@ -11,7 +11,7 @@ ] ], "1": [ - "versions.yml:md5,4322e3ce001be128a402386e9215e578" + "versions.yml:md5,c8f7017057430cb3694736c606c8eb6b" ], "bw": [ [ @@ -22,15 +22,15 @@ ] ], "versions": [ - "versions.yml:md5,4322e3ce001be128a402386e9215e578" + "versions.yml:md5,c8f7017057430cb3694736c606c8eb6b" ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.5" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-08-28T08:39:57.052601865" + "timestamp": "2025-12-11T09:38:52.912687858" }, "homo sapiens - bedmethyl, fai, list": { "content": [ @@ -44,7 +44,7 @@ ] ], "1": [ - "versions.yml:md5,4322e3ce001be128a402386e9215e578" + "versions.yml:md5,c8f7017057430cb3694736c606c8eb6b" ], "bw": [ [ @@ -55,15 +55,15 @@ ] ], "versions": [ - "versions.yml:md5,4322e3ce001be128a402386e9215e578" + "versions.yml:md5,c8f7017057430cb3694736c606c8eb6b" ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.5" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-08-28T08:39:35.618444189" + "timestamp": "2025-12-11T09:38:35.894897541" }, "homo sapiens - bedmethyl, fai, string": { "content": [ @@ -77,7 +77,7 @@ ] ], "1": [ - "versions.yml:md5,4322e3ce001be128a402386e9215e578" + "versions.yml:md5,c8f7017057430cb3694736c606c8eb6b" ], "bw": [ [ @@ -88,14 +88,14 @@ ] ], "versions": [ - "versions.yml:md5,4322e3ce001be128a402386e9215e578" + "versions.yml:md5,c8f7017057430cb3694736c606c8eb6b" ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.5" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-08-28T08:39:46.624865666" + "timestamp": "2025-12-11T09:38:44.647742811" } } \ No newline at end of file diff --git a/modules/nf-core/modkit/callmods/environment.yml b/modules/nf-core/modkit/callmods/environment.yml index 74d7fb53a557..07f12cf97a7b 100644 --- a/modules/nf-core/modkit/callmods/environment.yml +++ b/modules/nf-core/modkit/callmods/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::ont-modkit=0.5.0 + - bioconda::ont-modkit=0.6.0 diff --git a/modules/nf-core/modkit/callmods/main.nf b/modules/nf-core/modkit/callmods/main.nf index d9b5d7727a44..b0b1bea15ee6 100644 --- a/modules/nf-core/modkit/callmods/main.nf +++ b/modules/nf-core/modkit/callmods/main.nf @@ -4,8 +4,8 @@ process MODKIT_CALLMODS { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'https://depot.galaxyproject.org/singularity/ont-modkit:0.5.0--hcdda2d0_2' - : 'biocontainers/ont-modkit:0.5.0--hcdda2d0_2'}" + ? 'https://depot.galaxyproject.org/singularity/ont-modkit:0.6.0--hcdda2d0_0' + : 'biocontainers/ont-modkit:0.6.0--hcdda2d0_0'}" input: tuple val(meta), path(bam) diff --git a/modules/nf-core/modkit/callmods/tests/main.nf.test.snap b/modules/nf-core/modkit/callmods/tests/main.nf.test.snap index 834706a5c162..18251a71992e 100644 --- a/modules/nf-core/modkit/callmods/tests/main.nf.test.snap +++ b/modules/nf-core/modkit/callmods/tests/main.nf.test.snap @@ -35,7 +35,7 @@ ] ], "2": [ - "versions.yml:md5,03e4a3c3498e53548d4fd0deb17a425f" + "versions.yml:md5,90d284c04e15a618a6b9f893a889630a" ], "bam": [ [ @@ -54,19 +54,19 @@ ] ], "versions": [ - "versions.yml:md5,03e4a3c3498e53548d4fd0deb17a425f" + "versions.yml:md5,90d284c04e15a618a6b9f893a889630a" ] }, { "MODKIT_CALLMODS": { - "modkit": "0.5.0" + "modkit": "0.6.0" } } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.7" + "nf-test": "0.9.3", + "nextflow": "25.04.2" }, - "timestamp": "2025-10-13T16:38:07.173458603" + "timestamp": "2025-12-10T15:07:44.990852881" } } \ No newline at end of file diff --git a/modules/nf-core/modkit/repair/environment.yml b/modules/nf-core/modkit/repair/environment.yml index 074604f01e3a..f4a14f4abb43 100644 --- a/modules/nf-core/modkit/repair/environment.yml +++ b/modules/nf-core/modkit/repair/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - "bioconda::ont-modkit=0.5.0" + - "bioconda::ont-modkit=0.6.0" diff --git a/modules/nf-core/modkit/repair/main.nf b/modules/nf-core/modkit/repair/main.nf index 8f39f075900b..0a1ecc75109f 100644 --- a/modules/nf-core/modkit/repair/main.nf +++ b/modules/nf-core/modkit/repair/main.nf @@ -4,8 +4,8 @@ process MODKIT_REPAIR { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ont-modkit:0.5.0--hcdda2d0_1': - 'biocontainers/ont-modkit:0.5.0--hcdda2d0_1' }" + 'https://depot.galaxyproject.org/singularity/ont-modkit:0.6.0--hcdda2d0_0': + 'biocontainers/ont-modkit:0.6.0--hcdda2d0_0' }" input: tuple val(meta), path(before_trim), path(after_trim) diff --git a/modules/nf-core/modkit/repair/meta.yml b/modules/nf-core/modkit/repair/meta.yml index e76d2b8c2dde..5a88737fb1d9 100644 --- a/modules/nf-core/modkit/repair/meta.yml +++ b/modules/nf-core/modkit/repair/meta.yml @@ -1,7 +1,6 @@ # yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json name: "modkit_repair" -description: Modkit is a bioinformatics tool for working with modified bases in Oxford Nanopore sequencing data. The command `modkit reapir` is used for repairing the MM/ML tags on trimmed or hard-clipped ONT reads. - +description: Repair the MM/ML tags on trimmed or hard-clipped ONT reads using untrimmed ONT reads. keywords: - methylation - ont diff --git a/modules/nf-core/modkit/repair/tests/main.nf.test.snap b/modules/nf-core/modkit/repair/tests/main.nf.test.snap index 72907800060d..bb455c1bc5b3 100644 --- a/modules/nf-core/modkit/repair/tests/main.nf.test.snap +++ b/modules/nf-core/modkit/repair/tests/main.nf.test.snap @@ -35,7 +35,7 @@ ] ], "2": [ - "versions.yml:md5,3afdad70e5d4dcc2515104fe24fb32b2" + "versions.yml:md5,5eac7da8523b0c92aeffd6da42bf161a" ], "bam": [ [ @@ -54,19 +54,19 @@ ] ], "versions": [ - "versions.yml:md5,3afdad70e5d4dcc2515104fe24fb32b2" + "versions.yml:md5,5eac7da8523b0c92aeffd6da42bf161a" ] }, { "MODKIT_REPAIR": { - "modkit": "0.5.0" + "modkit": "0.6.0" } } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nf-test": "0.9.3", + "nextflow": "25.04.2" }, - "timestamp": "2025-09-26T14:41:41.621896549" + "timestamp": "2025-12-10T15:10:54.452622058" } } \ No newline at end of file From 37dbe45a498ba9d03c53959716ec1fd4a151dc39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Thu, 11 Dec 2025 11:58:21 +0100 Subject: [PATCH 63/83] Update `GLIMPSE` sbwf (#9524) * Update glimpse sbwf * Update test * Update filter operation * Update subworkflows/nf-core/vcf_impute_glimpse/main.nf Co-authored-by: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> * Update subworkflows/nf-core/vcf_impute_glimpse/main.nf Co-authored-by: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> * Update subworkflows/nf-core/vcf_impute_glimpse/main.nf Co-authored-by: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> * Update subworkflows/nf-core/vcf_impute_glimpse/main.nf Co-authored-by: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> * Update snapshot --------- Co-authored-by: LouisLeNezet Co-authored-by: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> --- modules/nf-core/glimpse/ligate/main.nf | 5 +- .../nf-core/vcf_impute_glimpse/main.nf | 95 +++++--- .../nf-core/vcf_impute_glimpse/meta.yml | 78 +++++-- .../vcf_impute_glimpse/tests/main.nf.test | 221 +++++++++++++----- .../tests/main.nf.test.snap | 192 ++++++++++----- .../vcf_impute_glimpse/tests/nextflow.config | 6 +- 6 files changed, 440 insertions(+), 157 deletions(-) diff --git a/modules/nf-core/glimpse/ligate/main.nf b/modules/nf-core/glimpse/ligate/main.nf index a62b24d62c85..885f5d5ddd5e 100644 --- a/modules/nf-core/glimpse/ligate/main.nf +++ b/modules/nf-core/glimpse/ligate/main.nf @@ -39,8 +39,11 @@ process GLIMPSE_LIGATE { stub: def prefix = task.ext.prefix ?: "${meta.id}" def suffix = task.ext.suffix ?: "vcf.gz" + + def create_cmd = suffix.endsWith(".gz") ? "echo '' | gzip >" : "touch" + """ - touch ${prefix}.${suffix} + ${create_cmd} ${prefix}.${suffix} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/subworkflows/nf-core/vcf_impute_glimpse/main.nf b/subworkflows/nf-core/vcf_impute_glimpse/main.nf index 9b6884df3e1c..9bfce0652756 100644 --- a/subworkflows/nf-core/vcf_impute_glimpse/main.nf +++ b/subworkflows/nf-core/vcf_impute_glimpse/main.nf @@ -1,59 +1,90 @@ -include { GLIMPSE_CHUNK } from '../../../modules/nf-core/glimpse/chunk/main' -include { GLIMPSE_PHASE } from '../../../modules/nf-core/glimpse/phase/main' -include { GLIMPSE_LIGATE } from '../../../modules/nf-core/glimpse/ligate/main' -include { BCFTOOLS_INDEX as INDEX_PHASE } from '../../../modules/nf-core/bcftools/index/main.nf' -include { BCFTOOLS_INDEX as INDEX_LIGATE } from '../../../modules/nf-core/bcftools/index/main.nf' +include { GLIMPSE_CHUNK } from '../../../modules/nf-core/glimpse/chunk/main' +include { GLIMPSE_PHASE } from '../../../modules/nf-core/glimpse/phase/main' +include { GLIMPSE_LIGATE } from '../../../modules/nf-core/glimpse/ligate/main' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_PHASE } from '../../../modules/nf-core/bcftools/index/main.nf' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_LIGATE } from '../../../modules/nf-core/bcftools/index/main.nf' workflow VCF_IMPUTE_GLIMPSE { take: - ch_input // channel (mandatory): [ meta, vcf, csi, sample, region, ref, ref_index, map ] + ch_vcf // channel (mandatory): [ meta, vcf, csi, infos ] + ch_ref // channel (mandatory): [ meta, vcf, csi, region ] + ch_chunks // channel (optional) : [ meta, regionin, regionout ] + ch_map // channel (optional) : [ meta, map ] + chunk // val (optional) : boolean to activate/deactivate chunking step main: ch_versions = channel.empty() - input_chunk = ch_input.map{ - meta, vcf, csi, _sample, region, _ref, _ref_index, _map -> - [ meta, vcf, csi, region] - } + if ( chunk == true ){ + // Error if pre-defined chunks are provided when chunking is activated + ch_chunks + .filter { _meta, regionin, regionout -> regionin.size() == 0 && regionout.size() == 0 } + .ifEmpty { error "ERROR: Cannot provide pre-defined chunks (regionin) when chunk=true. Please either set chunk=false to use provided chunks, or remove input chunks to enable automatic chunking." } - GLIMPSE_CHUNK ( input_chunk ) - ch_versions = ch_versions.mix( GLIMPSE_CHUNK.out.versions.first() ) + GLIMPSE_CHUNK ( ch_ref ) + ch_versions = ch_versions.mix( GLIMPSE_CHUNK.out.versions.first() ) - chunk_output = GLIMPSE_CHUNK.out.chunk_chr - .splitCsv(header: ['ID', 'Chr', 'RegionIn', 'RegionOut', 'Size1', 'Size2'], sep: "\t", skip: 0) - .map { meta, it -> [meta, it["RegionIn"], it["RegionOut"]]} + ch_chunks = GLIMPSE_CHUNK.out.chunk_chr + .splitCsv(header: ['ID', 'Chr', 'RegionIn', 'RegionOut', 'Size1', 'Size2'], sep: "\t", skip: 0) + .map { meta, it -> [meta, it["RegionIn"], it["RegionOut"]]} + } - phase_input = ch_input.map{ meta, vcf, csi, sample, _region, ref, ref_index, map -> [meta, vcf, csi, sample, ref, ref_index, map]} - .combine(chunk_output, by: 0) - .map{meta, vcf, csi, sample, ref, ref_index, map, regionin, regionout -> - [meta, vcf, csi, sample, regionin, regionout, ref, ref_index, map]} + ch_chunks + .filter { _meta, regionin, regionout -> regionin.size() > 0 && regionout.size() > 0 } + .ifEmpty { error "ERROR: ch_chunks channel is empty. Please provide a valid channel or set chunk parameter to true." } - GLIMPSE_PHASE ( phase_input ) // [meta, vcf, index, sample_infos, regionin, regionout, ref, ref_index, map] + ch_chunks_panel_map = ch_chunks + .combine(ch_ref, by: 0) + .combine(ch_map, by: 0) + + ch_chunks_panel_map.ifEmpty{ + error "ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input." + } + + phase_input = ch_vcf + .combine(ch_chunks_panel_map) + .map{ metaI, vcf, csi, sample, metaPC, regionin, regionout, ref, ref_index, _region, map -> [ + metaI + metaPC + ["regionout": regionout], + vcf, csi, sample, // target input + regionin, regionout, // chunks + ref, ref_index, map // reference panel + ]} + + GLIMPSE_PHASE ( phase_input ) ch_versions = ch_versions.mix(GLIMPSE_PHASE.out.versions.first() ) - INDEX_PHASE ( GLIMPSE_PHASE.out.phased_variants ) - ch_versions = ch_versions.mix( INDEX_PHASE.out.versions.first() ) + BCFTOOLS_INDEX_PHASE ( GLIMPSE_PHASE.out.phased_variants ) + ch_versions = ch_versions.mix( BCFTOOLS_INDEX_PHASE.out.versions.first() ) // Ligate all phased files in one and index it ligate_input = GLIMPSE_PHASE.out.phased_variants - .groupTuple( by: 0 ) - .combine( INDEX_PHASE.out.csi - .groupTuple( by: 0 ), - by: 0 + .join( BCFTOOLS_INDEX_PHASE.out.csi + .mix(BCFTOOLS_INDEX_PHASE.out.tbi) ) + .map{ meta, vcf, index -> + def keysToKeep = meta.keySet() - 'regionout' + [ meta.subMap(keysToKeep), vcf, index ] + } + .groupTuple() GLIMPSE_LIGATE ( ligate_input ) ch_versions = ch_versions.mix(GLIMPSE_LIGATE.out.versions.first() ) - INDEX_LIGATE ( GLIMPSE_LIGATE.out.merged_variants ) - ch_versions = ch_versions.mix( INDEX_LIGATE.out.versions.first() ) + BCFTOOLS_INDEX_LIGATE ( GLIMPSE_LIGATE.out.merged_variants ) + ch_versions = ch_versions.mix( BCFTOOLS_INDEX_LIGATE.out.versions.first() ) + + // Join imputed and index files + ch_vcf_index = GLIMPSE_LIGATE.out.merged_variants + .join( + BCFTOOLS_INDEX_LIGATE.out.tbi + .mix(BCFTOOLS_INDEX_LIGATE.out.csi) + ) emit: - chunk_chr = GLIMPSE_CHUNK.out.chunk_chr // channel: [ val(meta), txt ] - merged_variants = GLIMPSE_LIGATE.out.merged_variants // channel: [ val(meta), bcf ] - merged_variants_index = INDEX_LIGATE.out.csi // channel: [ val(meta), csi ] + chunk_chr = ch_chunks // channel: [ val(meta), regionin, regionout ] + vcf_index = ch_vcf_index // channel: [ val(meta), vcf, index ] - versions = ch_versions // channel: [ versions.yml ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/vcf_impute_glimpse/meta.yml b/subworkflows/nf-core/vcf_impute_glimpse/meta.yml index 81b3b4d5814d..1c076b97697f 100644 --- a/subworkflows/nf-core/vcf_impute_glimpse/meta.yml +++ b/subworkflows/nf-core/vcf_impute_glimpse/meta.yml @@ -12,20 +12,72 @@ components: - glimpse/ligate - bcftools/index input: - - ch_input: - type: file - description: | - Target dataset in VCF/BCF format defined at all variable positions. - Index file of the input VCF/BCF file containing genotype likelihoods. - File with sample names and ploidy information. - Target region, usually a full chromosome (e.g. chr20:1000000-2000000 or chr20). - Reference panel of haplotypes in VCF/BCF format. - Index file of the Reference panel file. - File containing the genetic map. - The file could possibly be without GT field (for efficiency reasons a file containing only the positions is recommended). - Structure: [ meta, vcf, csi, txt, region, ref_vcf, ref_csi, gmap ] + - ch_vcf: + description: Channel with target VCF files + structure: + - meta: + type: map + description: Metadata map + - vcf: + type: file + description: VCF file + pattern: "*.{vcf,bcf,vcf.gz}" + - index: + type: file + description: VCF index file + pattern: "*.{tbi,csi}" + - infos: + type: file + description: | + File containing ploidy information of each sample + pattern: "*.{txt, tsv}" + - ch_ref: + description: Channel with reference phased VCF files + structure: + - meta: + type: map + description: Metadata map + - vcf: + type: file + description: VCF file + pattern: "*.{vcf,bcf,vcf.gz}" + - index: + type: file + description: VCF index file + pattern: "*.{tbi,csi}" + - region: + type: string + description: Region to perform chunking on + pattern: "[chr]+[0-9]+:[0-9]+-[0-9]+" + - ch_chunks: + description: Channel with chunks data + structure: + - meta: + type: map + description: Metadata map that will be combined with the input data map + - regionin: + type: string + description: Chunk region without buffer + pattern: "[chr]+[0-9]+:[0-9]+-[0-9]+" + - regionout: + type: string + description: Chunk region with buffer + pattern: "[chr]+[0-9]+:[0-9]+-[0-9]+" + - ch_map: + description: Channel with genetic map data (optional) + structure: + - meta: + type: map + description: Metadata map + - map: + type: file + description: Map file in GLIMPSE format + pattern: "*.map" + - chunk: + type: boolean + description: Whether to perform chunking of the input data before imputation. output: - - chunk_chr: + - chunks: type: file description: | Tab delimited output txt file containing buffer and imputation regions. diff --git a/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test b/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test index a7dfec8a7ccc..8cc3387d17d7 100644 --- a/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test +++ b/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test @@ -4,6 +4,8 @@ nextflow_workflow { script "../main.nf" workflow "VCF_IMPUTE_GLIMPSE" + config "./nextflow.config" + tag "subworkflows" tag "bcftools/index" tag "subworkflows_nfcore" @@ -12,66 +14,86 @@ nextflow_workflow { tag "glimpse/ligate" tag "glimpse/chunk" - test("Should run without failures") { - config "./nextflow.config" - + test("homo_sapiens - vcf no sample, panel vcf region, no chunks, no map, chunking") { when { params { outdir = "tests/results" } workflow { """ - samples_infos = Channel.of('NA12878 2').collectFile(name: 'sampleinfos.txt') - - ch_panel = Channel.fromList([ - [[ chr:"chr21"], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz", checkIfExists:true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz.csi", checkIfExists:true)], - [[ chr:"chr22"], + input[0] = channel.of([ + [id:'input_vcf'], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + [] + ]) // input + input[1] = channel.of([ + [panel:'ref_panel', chr: "22"], 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)] - ]) - region = Channel.fromList([ - [[chr: "chr21", region: "chr21:16600000-16800000"], "chr21:16600000-16800000"], - [[chr: "chr22", region: "chr22:16600000-16800000"], "chr22:16600000-16800000"] - ]) + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz.csi", checkIfExists:true), + "chr22" + ]) // reference + input[2] = channel.of([ + [panel: 'ref_panel', chr: "22"], + [], [] + ]) // chunks + input[3] = channel.of([ + [panel: 'ref_panel', chr: "22"], + [] + ]) // map + input[4] = true // perform chunking + """ + } + } - input_vcf = Channel.fromList([ - [[ id:'NA12878'], // meta map - 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), - ], - [[ id:'NA19401'], // meta map - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA19401.chr21_22.1X.glimpse2.vcf.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA19401.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExists: true), - ] - ]) - input_vcf_multiple = input_vcf - .combine( samples_infos ) - .combine( region ) - .map{ metaI, vcf, index, sample, metaCR, region -> - [metaI + metaCR, vcf, index, sample, region ] - } + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.versions, + workflow.out.chunk_chr, + workflow.out.vcf_index.collect{ meta, vcf, index -> [ + meta, + path(vcf).getFileName().toString(), + path(index).getFileName().toString(), + path(vcf).vcf.summary, + path(vcf).vcf.header.getGenotypeSamples().sort(), + path(vcf).vcf.variantsMD5 + ]} + ).match() } + ) + } - ch_map = Channel.fromList([ - [[ chr: "chr21"], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr21.glimpse.map", checkIfExists: true) - ], - [[ chr: "chr22"], - file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.glimpse.map", checkIfExists: true) - ] - ]) + } - // Combine input and map depending on chromosome name - input[0] = input_vcf_multiple - .map{ metaIRC, vcf, index, sample, region -> - [metaIRC.subMap(["chr"]), metaIRC, vcf, index, sample, region] - } - .combine(ch_panel, by: 0) - .combine(ch_map, by: 0) - .map{ metaC, metaIRC, vcf, index, sample, region, ref, ref_index, map -> - [metaIRC, vcf, index, sample, region, ref, ref_index, map] - } + test("homo_sapiens - vcf and sample, panel vcf region, chunks, map, no chunking") { + when { + params { + outdir = "tests/results" + } + workflow { + """ + input[0] = channel.of([ + [id:'input_vcf'], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + [] + ]) // input + input[1] = channel.of([ + [panel:'ref_panel', chr: "22"], + 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" + ]) // reference + input[2] = channel.of( + [[panel: 'ref_panel', chr: "22"], "chr22:16570065-16597215", "chr22:16570065-16592216"], + [[panel: 'ref_panel', chr: "22"], "chr22:16587172-16609999", "chr22:16592229-16609999"] + ) // chunks + input[3] = channel.of([ + [panel: 'ref_panel', chr: "22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.glimpse.map", checkIfExists: true) + ]) // map + input[4] = false // perform chunking """ } } @@ -82,10 +104,12 @@ nextflow_workflow { { assert snapshot( workflow.out.versions, workflow.out.chunk_chr, - workflow.out.merged_variants.collect{ meta, vcf -> [ + workflow.out.vcf_index.collect{ meta, vcf, index -> [ meta, - file(vcf).name, + path(vcf).getFileName().toString(), + path(index).getFileName().toString(), path(vcf).vcf.summary, + path(vcf).vcf.header.getGenotypeSamples().sort(), path(vcf).vcf.variantsMD5 ]} ).match() } @@ -94,4 +118,97 @@ nextflow_workflow { } + test("homo_sapiens - stub test") { + options "-stub" + when { + workflow { + """ + input[0] = channel.of([ [id:'input_vcf'], [], [], [] ]) // input + input[1] = channel.of([ [panel:'ref_panel', chr: "22"], [], [], "chr22"]) // reference + input[2] = channel.of( + [[panel: 'ref_panel', chr: "22"], "chr22:16570065-16597215", "chr22:16570065-16592216"], + [[panel: 'ref_panel', chr: "22"], "chr22:16587172-16609999", "chr22:16592229-16609999"] + ) + input[3] = channel.of([ [panel: 'ref_panel', chr: "22"], [] ]) // Map + input[4] = false // perform chunking + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("homo_sapiens - error chunks provided and chunk is true") { + options "-stub" + when { + workflow { + """ + input[0] = channel.of([ [id:'input_vcf'], [], [], [] ]) // input + input[1] = channel.of([ [panel:'ref_panel', chr: "22"], [], [], "chr22"]) // reference + input[2] = channel.of( + [[panel: 'ref_panel', chr: "22"], "chr22:16570065-16597215", "chr22:16570065-16592216"], + [[panel: 'ref_panel', chr: "22"], "chr22:16587172-16609999", "chr22:16592229-16609999"] + ) // chunks + input[3] = channel.of([ [panel: 'ref_panel', chr: "22"], [] ]) // Map + input[4] = true // perform chunking + """ + } + } + then { + assertAll( + { assert workflow.failed }, + { assert workflow.errorMessage.contains("ERROR: Cannot provide pre-defined chunks (regionin) when chunk=true. Please either set chunk=false to use provided chunks, or remove input chunks to enable automatic chunking.") } + ) + } + } + + test("homo_sapiens - error no chunks provided and chunk is false") { + options "-stub" + when { + workflow { + """ + input[0] = channel.of([ [id:'input_vcf'], [], [], [] ]) // input + input[1] = channel.of([ [panel:'ref_panel', chr: "22"], [], [], "chr22"]) // reference + input[2] = channel.of([ [panel: 'ref_panel', chr: "22"], [], [] ]) // chunks + input[3] = channel.of([ [panel: 'ref_panel', chr: "22"], [] ]) // map + input[4] = false // perform chunking + """ + } + } + then { + assertAll( + { assert workflow.failed }, + { assert workflow.errorMessage.contains("ERROR: ch_chunks channel is empty. Please provide a valid channel or set chunk parameter to true.") } + ) + } + } + + test("homo_sapiens - error empty joint") { + options "-stub" + when { + workflow { + """ + input[0] = channel.of([ [id:'input_vcf'], [], [], [] ]) // input + input[1] = channel.of([ [panel:'ref_panel', chr: "22"], [], [], "chr22"]) // reference + input[2] = channel.of( + [[panel: 'ref_panel', chr: "22"], "chr22:16570065-16597215", "chr22:16570065-16592216"], + [[panel: 'ref_panel', chr: "22"], "chr22:16587172-16609999", "chr22:16592229-16609999"] + ) // chunks + input[3] = channel.of([ [panel: 'ref_panel_1', chr: "22"], [] ]) // Wrong panel + input[4] = false // perform chunking + """ + } + } + then { + assertAll( + { assert workflow.failed }, + { assert workflow.errorMessage.contains("ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input.") } + ) + } + } + } diff --git a/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test.snap b/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test.snap index d0174f8cacc8..d6371b1f5d4b 100644 --- a/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test.snap +++ b/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test.snap @@ -1,94 +1,174 @@ { - "Should run without failures": { + "homo_sapiens - vcf no sample, panel vcf region, no chunks, no map, chunking": { "content": [ [ "versions.yml:md5,21a662d09502bd6516ec62b72e4fb182", "versions.yml:md5,227d8e960e4382d8a615e040b874fc27", - "versions.yml:md5,4c01309242fd8da3ddbde9fab54aae4c", "versions.yml:md5,7ae4d2b0252f9382dd08d783b7a234d2", - "versions.yml:md5,c7bdac5a09390d02a95e5042a2fd133e" + "versions.yml:md5,9fbf16c8cc7fbd7c71287273e4574c63", + "versions.yml:md5,aaac5faff61fcbf4cc1aea0fdbd824ee" ], [ [ { - "id": "NA12878", - "chr": "chr21", - "region": "chr21:16600000-16800000" + "panel": "ref_panel", + "chr": "22" }, - "NA12878_chr21:16600000-16800000_chunk.txt:md5,775240b195e782b3b83adf52e0d17089" - ], + "chr22:16570065-16609999", + "chr22:16570065-16609999" + ] + ], + [ [ { - "id": "NA12878", - "chr": "chr22", - "region": "chr22:16600000-16800000" + "id": "input_vcf", + "panel": "ref_panel", + "chr": "22" }, - "NA12878_chr22:16600000-16800000_chunk.txt:md5,7ac5d116bc3357a154946576c21060cd" - ], + "input_vcf_22_ligate.vcf.gz", + "input_vcf_22_ligate.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=903, phased=false, phasedAutodetect=false]", + [ + "NA12878" + ], + "fbe935ae0eb720944813f82e5ad68758" + ] + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-11T11:41:46.017234735" + }, + "homo_sapiens - vcf and sample, panel vcf region, chunks, map, no chunking": { + "content": [ + [ + "versions.yml:md5,21a662d09502bd6516ec62b72e4fb182", + "versions.yml:md5,7ae4d2b0252f9382dd08d783b7a234d2", + "versions.yml:md5,9fbf16c8cc7fbd7c71287273e4574c63", + "versions.yml:md5,aaac5faff61fcbf4cc1aea0fdbd824ee" + ], + [ [ { - "id": "NA19401", - "chr": "chr21", - "region": "chr21:16600000-16800000" + "panel": "ref_panel", + "chr": "22" }, - "NA19401_chr21:16600000-16800000_chunk.txt:md5,775240b195e782b3b83adf52e0d17089" + "chr22:16570065-16597215", + "chr22:16570065-16592216" ], [ { - "id": "NA19401", - "chr": "chr22", - "region": "chr22:16600000-16800000" + "panel": "ref_panel", + "chr": "22" }, - "NA19401_chr22:16600000-16800000_chunk.txt:md5,7ac5d116bc3357a154946576c21060cd" + "chr22:16587172-16609999", + "chr22:16592229-16609999" ] ], [ [ { - "id": "NA12878", - "chr": "chr21", - "region": "chr21:16600000-16800000" + "id": "input_vcf", + "panel": "ref_panel", + "chr": "22" }, - "NA12878_chr21_null_ligate.vcf.gz", - "VcfFile [chromosomes=[chr21], sampleCount=1, variantCount=211, phased=false, phasedAutodetect=false]", - "66d0bfb31b037fb57d6b56e65b7cd6a7" + "input_vcf_22_ligate.vcf.gz", + "input_vcf_22_ligate.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=903, phased=false, phasedAutodetect=false]", + [ + "NA12878" + ], + "5e2d629c8d0371dc6b5928a32a8bc5c5" + ] + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-11T11:41:57.921667365" + }, + "homo_sapiens - stub test": { + "content": [ + { + "0": [ + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16570065-16597215", + "chr22:16570065-16592216" + ], + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16587172-16609999", + "chr22:16592229-16609999" + ] ], - [ - { - "id": "NA12878", - "chr": "chr22", - "region": "chr22:16600000-16800000" - }, - "NA12878_chr22_null_ligate.vcf.gz", - "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=266, phased=false, phasedAutodetect=false]", - "58751684e0168ad0485ba3510e0cfd3e" + "1": [ + [ + { + "id": "input_vcf", + "panel": "ref_panel", + "chr": "22" + }, + "input_vcf_22_ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "input_vcf_22_ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ], - [ - { - "id": "NA19401", - "chr": "chr21", - "region": "chr21:16600000-16800000" - }, - "NA19401_chr21_null_ligate.vcf.gz", - "VcfFile [chromosomes=[chr21], sampleCount=1, variantCount=211, phased=false, phasedAutodetect=false]", - "66d0bfb31b037fb57d6b56e65b7cd6a7" + "2": [ + "versions.yml:md5,21a662d09502bd6516ec62b72e4fb182", + "versions.yml:md5,7ae4d2b0252f9382dd08d783b7a234d2", + "versions.yml:md5,9fbf16c8cc7fbd7c71287273e4574c63", + "versions.yml:md5,aaac5faff61fcbf4cc1aea0fdbd824ee" ], - [ - { - "id": "NA19401", - "chr": "chr22", - "region": "chr22:16600000-16800000" - }, - "NA19401_chr22_null_ligate.vcf.gz", - "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=266, phased=false, phasedAutodetect=false]", - "58751684e0168ad0485ba3510e0cfd3e" + "chunk_chr": [ + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16570065-16597215", + "chr22:16570065-16592216" + ], + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16587172-16609999", + "chr22:16592229-16609999" + ] + ], + "vcf_index": [ + [ + { + "id": "input_vcf", + "panel": "ref_panel", + "chr": "22" + }, + "input_vcf_22_ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "input_vcf_22_ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,21a662d09502bd6516ec62b72e4fb182", + "versions.yml:md5,7ae4d2b0252f9382dd08d783b7a234d2", + "versions.yml:md5,9fbf16c8cc7fbd7c71287273e4574c63", + "versions.yml:md5,aaac5faff61fcbf4cc1aea0fdbd824ee" ] - ] + } ], "meta": { "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-27T11:10:39.309436558" + "timestamp": "2025-12-11T11:42:08.199660928" } } \ No newline at end of file diff --git a/subworkflows/nf-core/vcf_impute_glimpse/tests/nextflow.config b/subworkflows/nf-core/vcf_impute_glimpse/tests/nextflow.config index 09ab685850de..8f4ae66f5bc4 100644 --- a/subworkflows/nf-core/vcf_impute_glimpse/tests/nextflow.config +++ b/subworkflows/nf-core/vcf_impute_glimpse/tests/nextflow.config @@ -1,12 +1,12 @@ process { withName: GLIMPSE_CHUNK { - ext.prefix = { "${meta.id}_${meta.region}_chunk" } + ext.prefix = { "${meta.panel}_${meta.chr}_chunk" } ext.args = "--window-size 50000 --buffer-size 1000" } withName: GLIMPSE_PHASE { - ext.prefix = { "${meta.id}_${meta.region}_${meta.ref}_phase_${input_region.replace(":","_")}" } + ext.prefix = { "${meta.id}_${meta.regionout? meta.regionout.replace(":","_") : meta.chr}" } } withName: GLIMPSE_LIGATE { - ext.prefix = { "${meta.id}_${meta.chr}_${meta.ref}_ligate" } + ext.prefix = { "${meta.id}_${meta.chr}_ligate" } } } From 03cae33c2aaf0a86848bece415887c375ea124c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Thu, 11 Dec 2025 12:22:51 +0100 Subject: [PATCH 64/83] Add quilt imputation subworkflow (#9443) * Add sbwf quilt * Fix tags * Update meta * Use modules repo files --- modules/nf-core/quilt/quilt/main.nf | 11 +- .../nf-core/quilt/quilt/tests/main.nf.test | 75 +++--- .../quilt/quilt/tests/main.nf.test.snap | 189 ++++++------- .../nf-core/quilt/quilt/tests/nextflow.config | 3 - subworkflows/nf-core/bam_impute_quilt/main.nf | 77 ++++++ .../nf-core/bam_impute_quilt/meta.yml | 139 ++++++++++ .../bam_impute_quilt/tests/main.nf.test | 252 ++++++++++++++++++ .../bam_impute_quilt/tests/main.nf.test.snap | 181 +++++++++++++ .../bam_impute_quilt/tests/nextflow.config | 19 ++ 9 files changed, 796 insertions(+), 150 deletions(-) create mode 100644 subworkflows/nf-core/bam_impute_quilt/main.nf create mode 100644 subworkflows/nf-core/bam_impute_quilt/meta.yml create mode 100644 subworkflows/nf-core/bam_impute_quilt/tests/main.nf.test create mode 100644 subworkflows/nf-core/bam_impute_quilt/tests/main.nf.test.snap create mode 100644 subworkflows/nf-core/bam_impute_quilt/tests/nextflow.config diff --git a/modules/nf-core/quilt/quilt/main.nf b/modules/nf-core/quilt/quilt/main.nf index eddb11b58080..3003ce3c12d6 100644 --- a/modules/nf-core/quilt/quilt/main.nf +++ b/modules/nf-core/quilt/quilt/main.nf @@ -25,7 +25,7 @@ process QUILT_QUILT { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" def suffix = task.ext.suffix ?: "vcf.gz" - def extensions = bams.collect { it.extension } + def extensions = bams.collect { path -> path.extension } def extension = extensions.flatten().unique() def list_command = extension == ["bam"] ? "--bamlist=" : extension == ["cram"] ? "--reference=${fasta} --cramlist=" : "" @@ -33,6 +33,9 @@ process QUILT_QUILT { def posfile_command = posfile ? "--posfile=${posfile}" : "" def phasefile_command = phasefile ? "--phasefile=${phasefile}" : "" 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"} @@ -52,10 +55,10 @@ process QUILT_QUILT { $phasefile_command \\ $samplename_command \\ --chr=$chr \\ - --regionStart=$regions_start \\ - --regionEnd=$regions_end \\ + $start_command \\ + $end_command \\ + $buffer_command \\ --nGen=$ngen \\ - --buffer=$buffer \\ --nCores=$task.cpus \\ --outputdir="." \\ --reference_haplotype_file=$reference_haplotype_file \\ diff --git a/modules/nf-core/quilt/quilt/tests/main.nf.test b/modules/nf-core/quilt/quilt/tests/main.nf.test index 37c518a88c4f..06ded6812234 100644 --- a/modules/nf-core/quilt/quilt/tests/main.nf.test +++ b/modules/nf-core/quilt/quilt/tests/main.nf.test @@ -13,7 +13,7 @@ nextflow_process { config "./nextflow.config" - test("QUILT") { + test("homo_sapiens - bam, hap, legend, posfile, phasefile, map - fasta") { setup { run("BCFTOOLS_QUERY") { script "../../../bcftools/query/main.nf" @@ -21,8 +21,8 @@ nextflow_process { """ input[0] = [ [id: 'NA12878'], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi', checkIfExists: true) + 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] = [] @@ -42,44 +42,31 @@ nextflow_process { """ } } - - run("GAWK", alias: "GAWK_POSFILE") { - script "../../../gawk/main.nf" - process { - """ - program = Channel.of('BEGIN{OFS=\"\\t\"} NR>1 {split(\$1, a, \"[:-_]\"); print a[1],\$2,\$3,\$4}').collectFile(name: 'program.txt', newLine: true) - input[0] = [ - [id: 'NA12878'], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.legend.gz', checkIfExists: true) - ] - input[1] = program - input[2] = false - """ - } - } } when { params{ quilt_args = "--save_prepared_reference=TRUE --make_plots=TRUE --seed=1" - bcftools_query_args = "-f '[%GT]\\n'" - bcftools_query_suffix = "genfile.txt" - gawk_posfile_suffix = "posfile.txt" - gawk_name_suffix = "genfile.name.txt" + bcftools_query_args = "-f '[%GT]\\n' -r chr22" + bcftools_query_suffix = "phasefile.txt" + gawk_name_suffix = "phasefile.name.txt" } process { """ input[0] = Channel.of([ [ id:'NA12878', chr:'chr22' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam.bai', checkIfExists: true), + 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.hap.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.legend.gz', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.legend.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.posfile', checkIfExists: true), ]) - .combine(GAWK_POSFILE.out.output.map{ it[1] }) .combine(GAWK_NAME.out.output.map{ it[1] }) - .combine(Channel.of([[], "chr22", "16570000", "16610000", "100", "10000", []])) + .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", checkIfExist:true) + ])) input[1] = [ [id: 'GRCh38'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), @@ -96,13 +83,15 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - process.out.vcf, process.out.tbi, list.sort(), process.out.rdata, process.out.versions, - process.out.vcf.collect{ path(it[1]).vcf.header.getGenotypeSamples().sort() }, - process.out.vcf.collect{ path(it[1]).vcf.variantsMD5 } + process.out.vcf.collect{ meta, vcf -> [ + meta, + path(vcf).vcf.header.getGenotypeSamples().sort(), + path(vcf).vcf.variantsMD5 + ]} ).match() } ) } @@ -156,8 +145,8 @@ nextflow_process { """ input[0] = [ [ id:'test', chr:'chr22' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam.bai', checkIfExists: true), + 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.hap.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.legend.gz', checkIfExists: true), @@ -174,12 +163,14 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - process.out.vcf, process.out.tbi, process.out.rdata, process.out.versions, - process.out.vcf.collect{ path(it[1]).vcf.header.getGenotypeSamples().sort() }, - process.out.vcf.collect{ path(it[1]).vcf.variantsMD5 } + process.out.vcf.collect{ meta, vcf -> [ + meta, + path(vcf).vcf.header.getGenotypeSamples().sort(), + path(vcf).vcf.variantsMD5 + ]} ).match() } ) } @@ -193,7 +184,7 @@ nextflow_process { process { """ bamlist = Channel.of( - "NA12878.chr22.1X.bam", + "NA12878.chr21_22.1X.bam", ).collectFile(name : 'bamlist.txt', newLine : true) bamnames = Channel.of( @@ -202,8 +193,8 @@ nextflow_process { ch_input = Channel.of([ [ id:'test', chr:'chr20' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam.bai', checkIfExists: true) + 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) @@ -225,12 +216,14 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - process.out.vcf, process.out.tbi, process.out.rdata, process.out.versions, - process.out.vcf.collect{ path(it[1]).vcf.header.getGenotypeSamples().sort() }, - process.out.vcf.collect{ path(it[1]).vcf.variantsMD5 } + process.out.vcf.collect{ meta, vcf -> [ + meta, + path(vcf).vcf.header.getGenotypeSamples().sort(), + path(vcf).vcf.variantsMD5 + ]} ).match() } ) } diff --git a/modules/nf-core/quilt/quilt/tests/main.nf.test.snap b/modules/nf-core/quilt/quilt/tests/main.nf.test.snap index 4419261a415e..c84541069885 100644 --- a/modules/nf-core/quilt/quilt/tests/main.nf.test.snap +++ b/modules/nf-core/quilt/quilt/tests/main.nf.test.snap @@ -1,5 +1,5 @@ { - "QUILT": { + "QUILT - stub": { "content": [ [ [ @@ -7,7 +7,7 @@ "id": "NA12878", "chr": "chr22" }, - "NA12878.vcf.gz:md5,21ad07e950d81d720f491aa15d36a16c" + "NA12878.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], [ @@ -16,7 +16,7 @@ "id": "NA12878", "chr": "chr22" }, - "NA12878.vcf.gz.tbi:md5,eaf83bceb70eb8b05412b9135a82681f" + "NA12878.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], [ @@ -60,128 +60,80 @@ "chr": "chr22" }, [ - "QUILT_prepared_reference.chr22.16570000.16610000.RData:md5,e3171d960e8b315350bd6604785d4c05" + "QUILT_prepared_reference.chr22.16570000.16610000.RData:md5,d41d8cd98f00b204e9800998ecf8427e" ] ] ], [ "versions.yml:md5,6d07cd60389ff6981a44004872bd16b7" - ], - [ - [ - "NA12878" - ] - ], - [ - "19b4ad0b183799e00fb50c7c58bbd2f3" ] ], "meta": { - "nf-test": "0.9.1", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-02-24T14:54:22.327646817" + "timestamp": "2025-11-27T11:55:40.290647067" }, - "QUILT - stub": { + "QUILT no optional files": { "content": [ [ [ { - "id": "NA12878", + "id": "test", "chr": "chr22" }, - "NA12878.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test.vcf.gz.tbi:md5,4fed28161b3da64b2f8302e3cbb4c0d9" ] ], [ [ { - "id": "NA12878", + "id": "test", "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" + "versions.yml:md5,6d07cd60389ff6981a44004872bd16b7" ], [ [ { - "id": "NA12878", + "id": "test", "chr": "chr22" }, [ - "QUILT_prepared_reference.chr22.16570000.16610000.RData:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "NA12878" + ], + "bb640c38eea9b8df18d1debad11a21e0" ] - ], - [ - "versions.yml:md5,6d07cd60389ff6981a44004872bd16b7" ] ], "meta": { - "nf-test": "0.9.1", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-02-24T14:10:30.530507444" + "timestamp": "2025-11-27T11:55:49.398386631" }, - "QUILT no optional files": { + "QUILT with bamlist and renaming": { "content": [ [ [ { "id": "test", - "chr": "chr22" - }, - "test.vcf.gz:md5,9b840a534ff04b77c848106809760770" - ] - ], - [ - [ - { - "id": "test", - "chr": "chr22" + "chr": "chr20" }, - "test.vcf.gz.tbi:md5,ab35a6f93715b251e2429a69cfff038d" + "test.vcf.gz.tbi:md5,487166bf9532223bbde1156b80e5cfa3" ] ], [ [ { "id": "test", - "chr": "chr22" + "chr": "chr20" }, [ @@ -193,47 +145,76 @@ ], [ [ - "NA12878" + { + "id": "test", + "chr": "chr20" + }, + [ + "Mysample1" + ], + "bb640c38eea9b8df18d1debad11a21e0" ] - ], - [ - "a13c1e8a78af08c6ba185678614ff4bf" ] ], "meta": { - "nf-test": "0.9.1", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-02-24T14:54:47.045399644" + "timestamp": "2025-11-27T11:55:58.4211794" }, - "QUILT with bamlist and renaming": { + "homo_sapiens - bam, hap, legend, posfile, phasefile, map - fasta": { "content": [ [ [ { - "id": "test", - "chr": "chr20" + "id": "NA12878", + "chr": "chr22" }, - "test.vcf.gz:md5,fc56c37a0ea0f1b9a6a75064c4173c5a" + "NA12878.vcf.gz.tbi:md5,da74a7127dff516779a73e560010ec12" ] ], [ - [ - { - "id": "test", - "chr": "chr20" - }, - "test.vcf.gz.tbi:md5,8fe810022afc931295305c415f1f4892" - ] + "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": "test", - "chr": "chr20" + "id": "NA12878", + "chr": "chr22" }, [ - + "QUILT_prepared_reference.chr22.16570000.16610000.RData:md5,d4ba79eb3450d7892c5e9ee77d61e361" ] ] ], @@ -242,17 +223,21 @@ ], [ [ - "Mysample1" + { + "id": "NA12878", + "chr": "chr22" + }, + [ + "NA12878" + ], + "f5c315626c7b8dc416e9804234db46bf" ] - ], - [ - "a13c1e8a78af08c6ba185678614ff4bf" ] ], "meta": { - "nf-test": "0.9.1", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2025-02-24T14:55:00.907750715" + "timestamp": "2025-11-27T11:55:33.818197267" } } \ No newline at end of file diff --git a/modules/nf-core/quilt/quilt/tests/nextflow.config b/modules/nf-core/quilt/quilt/tests/nextflow.config index 3a3bfe569bdb..55300fd5d60a 100644 --- a/modules/nf-core/quilt/quilt/tests/nextflow.config +++ b/modules/nf-core/quilt/quilt/tests/nextflow.config @@ -10,9 +10,6 @@ process { ext.args = {"${params.bcftools_query_args}"} ext.suffix = {"${params.bcftools_query_suffix}"} } - withName: GAWK_POSFILE { - ext.suffix = {"${params.gawk_posfile_suffix}"} - } withName: GAWK_NAME { ext.suffix = {"${params.gawk_name_suffix}"} } diff --git a/subworkflows/nf-core/bam_impute_quilt/main.nf b/subworkflows/nf-core/bam_impute_quilt/main.nf new file mode 100644 index 000000000000..ffae2fe7fcc7 --- /dev/null +++ b/subworkflows/nf-core/bam_impute_quilt/main.nf @@ -0,0 +1,77 @@ +include { QUILT_QUILT } from '../../../modules/nf-core/quilt/quilt' +include { GLIMPSE2_LIGATE } from '../../../modules/nf-core/glimpse2/ligate' +include { BCFTOOLS_INDEX } from '../../../modules/nf-core/bcftools/index' + +workflow BAM_IMPUTE_QUILT { + + take: + ch_input // channel (mandatory): [ [id], [bam], [bai], bampaths, bamnames ] + ch_hap_legend // channel (mandatory): [ [panel, chr], hap, legend ] + ch_posfile // channel (mandatory): [ [panel, chr], posfile ] + ch_chunks // channel (optional) : [ [panel, chr], chr, start, end ] + ch_map // channel (optional) : [ [panel, chr], map ] + ch_fasta // channel (optional) : [ [genome], fa, fai ] + n_gen // integer: Number of generations since founding or mixing + buffer // integer: Buffer of region to perform imputation over + + main: + + ch_versions = channel.empty() + + // Make final channel with parameters + ch_parameters = ch_hap_legend + .combine(ch_posfile, by: 0) + .combine(ch_map, by: 0) + .combine(ch_chunks, by: 0) + + ch_parameters.ifEmpty{ + error "ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input." + } + + ch_bam_params = ch_input + .combine(ch_parameters) + .map{ + metaI, bam, bai, bampath, bamname, metaPC, hap, legend, posfile, gmap, chr, start, end -> + def regionout = "${chr}" + if (start != [] && end != []) { + regionout = "${chr}:${start}-${end}" + } + [ + metaPC + metaI + ["regionout": regionout], + bam, bai, bampath, bamname, + hap, legend, + posfile, [], [], + chr, start, end, n_gen, buffer, gmap + ] + } + + QUILT_QUILT( ch_bam_params, ch_fasta ) + ch_versions = ch_versions.mix( QUILT_QUILT.out.versions.first() ) + + // Ligate all phased files in one and index it + ligate_input = QUILT_QUILT.out.vcf + .join( QUILT_QUILT.out.tbi ) + .map{ meta, vcf, index -> + def keysToKeep = meta.keySet() - ['regionout'] + [ meta.subMap(keysToKeep), vcf, index ] + } + .groupTuple() + + GLIMPSE2_LIGATE( ligate_input ) + ch_versions = ch_versions.mix( GLIMPSE2_LIGATE.out.versions.first() ) + + BCFTOOLS_INDEX( GLIMPSE2_LIGATE.out.merged_variants ) + ch_versions = ch_versions.mix( BCFTOOLS_INDEX.out.versions.first() ) + + // Join imputed and index files + ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants + .join( + BCFTOOLS_INDEX.out.tbi + .mix(BCFTOOLS_INDEX.out.csi) + ) + + emit: + vcf_index = ch_vcf_index // channel: [ [id, chr], vcf, tbi ] + versions = ch_versions // channel: [ versions.yml ] + +} diff --git a/subworkflows/nf-core/bam_impute_quilt/meta.yml b/subworkflows/nf-core/bam_impute_quilt/meta.yml new file mode 100644 index 000000000000..a3964242921e --- /dev/null +++ b/subworkflows/nf-core/bam_impute_quilt/meta.yml @@ -0,0 +1,139 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "BAM_IMPUTE_QUILT" +description: | + Subworkflow to impute BAM files using QUILT software. + Variants location to impute are obtain through the tsv file given +keywords: + - BAM + - imputation + - quilt +components: + - gawk + - quilt/quilt + - bcftools/index + - glimpse2/ligate +input: + - ch_input: + description: Channel with input data + structure: + - meta: + type: map + description: Metadata map + - file: + type: file + description: List of input BAM files + pattern: "*.bam" + - index: + type: file + description: List of input index file + pattern: "*.{bai,csi}" + - bampaths: + type: file + description: | + File containing the list of BAM/CRAM files to be phased. + One file per line. + pattern: "*.{txt,tsv}" + - bamnames: + type: file + description: | + File containing the sample names of each BAM files listed in bampaths. + One file per line. + pattern: "*.{txt,tsv}" + - ch_hap_legend: + description: Channel with reference panel variants data + structure: + - meta: + type: map + description: | + Metadata map that will be combined with the input data map + Need to have the "chr" as chromosome name and "id" as panel name + - hap: + type: file + description: Panel VCF haplotypes files by chromosomes + pattern: "*.hap[.gz]+" + - legend: + type: file + description: Panel VCF legend files by chromosomes + pattern: "*.legend[.gz]+" + - ch_posfile: + description: Channel with position to call variants by chromosomes + structure: + - meta: + type: map + description: | + Metadata map with chromosome information + - tsv: + type: file + description: Position to impute variants file in TSV format (chromosome, position, ref, alt) + - ch_chunks: + description: Channel with chromosome chunks data + structure: + - meta: + type: map + description: Metadata map with chromosome information + - chr: + type: string + description: Chromosome name + - start: + type: integer + description: Start position of the chunk + - end: + type: integer + description: End position of the chunk + - ch_map: + description: Channel with genetic map data + structure: + - meta: + type: map + description: | + Metadata map with chromosome information + - map: + type: file + description: Stitch format genetic map files + pattern: "*.map" + - ch_fasta: + description: Channel with reference genome data + structure: + - meta: + type: map + description: Metadata map + - fasta: + type: file + description: FASTA file of the reference genome + pattern: "*.fa[sta]+" + - fai: + type: file + description: FASTA index file of the reference genome + pattern: "*.fai" + - n_gen: + type: integer + description: Number of generations since founding or mixing + - buffer: + type: integer + description: Buffer of region to perform imputation over +output: + - vcf_index: + description: Channel with imputed VCF files + structure: + - meta: + type: map + description: | + Metadata map combined with the posfile, chunks and map data map. + - vcf: + type: file + description: VCF imputed file + pattern: "*.{vcf,bcf,vcf.gz}" + - index: + type: file + description: VCF index file + pattern: "*.{tbi,csi}" + - versions: + description: Channel containing software versions file + structure: + - versions.yml: + type: file + description: File containing versions of the software used +authors: + - "@louislenezet" +maintainers: + - "@louislenezet" diff --git a/subworkflows/nf-core/bam_impute_quilt/tests/main.nf.test b/subworkflows/nf-core/bam_impute_quilt/tests/main.nf.test new file mode 100644 index 000000000000..6946365c300a --- /dev/null +++ b/subworkflows/nf-core/bam_impute_quilt/tests/main.nf.test @@ -0,0 +1,252 @@ +nextflow_workflow { + + name "Test Subworkflow BAM_IMPUTE_QUILT" + script "../main.nf" + config "./nextflow.config" + + workflow "BAM_IMPUTE_QUILT" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/bam_impute_quilt" + + tag "quilt" + tag "quilt/quilt" + tag "bcftools" + tag "bcftools/index" + tag "glimpse2" + tag "glimpse2/ligate" + + test("Impute with quilt one individual, no renaming, posfile, no chunks, no map, no fasta") { + when { + params{ + quilt_args = "--seed=1" + } + workflow { + """ + bampath = channel.of("NA12878.chr21_22.1X.bam").collectFile(name: 'bampath.txt', newLine: true) + input[0] = channel.of([ + [id: "allid"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam.bai", checkIfExist:true) + ]) + .combine(bampath) + .combine(channel.of([[]])) // input + input[1] = channel.of([ + [id: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.hap.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.legend.gz", checkIfExist:true) + ]) + input[2] = channel.of([ + [id: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.posfile", checkIfExist:true) + ]) // posfile + input[3] = channel.of( + [[chr: "chr22", id: "1000GP"], "chr22", [], []] + ) // chunks + input[4] = channel.of([ [id: "1000GP", chr: "chr22"], [] ]) // map + input[5] = channel.of([ [id: "GRCh38"], [], [] ]).collect() // fasta + input[6] = 100 // ngen + input[7] = [] // buffer + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.vcf_index.collect{ meta, vcf, index -> [ + meta, + path(vcf).getFileName().toString(), + path(index).getFileName().toString(), + path(vcf).vcf.summary, + path(vcf).vcf.header.getGenotypeSamples().sort(), + path(vcf).vcf.variantsMD5 + ]}, + workflow.out.versions, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + + test("Impute with quilt two individual bam, renaming, posfile, chunks, map, no fasta") { + when { + params{ + quilt_args = "--seed=1" + } + workflow { + """ + bampath = Channel.of( + "NA12878.chr21_22.1X.bam", + "NA19401.chr21_22.1X.bam" + ).collectFile(name: 'bampath.txt', newLine: true) + bamname = Channel.of( + "MySample1", + "MySample2" + ).collectFile(name: 'bamname.txt', newLine: true) + ch_samples = channel.of([ + [id: "allid"], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA19401.chr21_22.1X.bam", checkIfExist:true) + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam.bai", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA19401.chr21_22.1X.bam.bai", checkIfExist:true) + ] + ]) + input[0] = ch_samples.combine(bampath).combine(bamname) // input + input[1] = channel.of( + [ + [id: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.hap.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.legend.gz", checkIfExist:true) + ],[ + [id: "1000GP", chr: "chr21"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.hap.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.legend.gz", checkIfExist:true) + ]) + input[2] = channel.of([ + [id: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.posfile", checkIfExist:true) + ],[ + [id: "1000GP", chr: "chr21"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.posfile", checkIfExist:true) + ]) // posfile + input[3] = channel.of( + [[chr: "chr22", id: "1000GP"], "chr22", 16570065, 16592216], + [[chr: "chr22", id: "1000GP"], "chr22", 16592229, 16609999], + [[chr: "chr21", id: "1000GP"], "chr21", 16570065, 16592216], + [[chr: "chr21", id: "1000GP"], "chr21", 16592229, 16609999] + ) // chunks + input[4] = Channel.of([ + [id: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.stitch.map", checkIfExist:true) + ],[ + [id: "1000GP", chr: "chr21"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr21.stitch.map", checkIfExist:true) + ]) // map + input[5] = channel.of([ [id: "GRCh38"], [], [] ]).collect() + input[6] = 100 + input[7] = 10000 + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.vcf_index.collect{ meta, vcf, index -> [ + meta, + path(vcf).getFileName().toString(), + path(index).getFileName().toString(), + path(vcf).vcf.summary, + path(vcf).vcf.header.getGenotypeSamples().sort(), + path(vcf).vcf.variantsMD5 + ]}, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + + test("homo_sapiens - empty channels - stub") { + options "-stub" + when { + params{ + quilt_args = "--seed=1" + } + workflow { + """ + bampath = Channel.of("NA12878.chr21_22.1X.bam").collectFile(name: 'bampath.txt', newLine: true) + bamname = Channel.of("MySample1").collectFile(name: 'bamname.txt', newLine: true) + ch_samples = channel.of([ + [id: "allid"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam.bai", checkIfExist:true) + ]) + input[0] = ch_samples.combine(bampath).combine(bamname) // input + input[1] = channel.of( + [[id: "1000GP", chr: "chr22"], [], []], + [[id: "1000GP", chr: "chr21"], [], []] + ) // hap legend + input[2] = channel.of( + [[id: "1000GP", chr: "chr22"], []], + [[id: "1000GP", chr: "chr21"], []] + ) // posfile + input[3] = channel.of( + [[chr: "chr22", id: "1000GP"], "chr22", 16570065, 16592216], + [[chr: "chr22", id: "1000GP"], "chr22", 16592229, 16609999], + [[chr: "chr21", id: "1000GP"], "chr21", 16570065, 16592216], + [[chr: "chr21", id: "1000GP"], "chr21", 16592229, 16609999] + ) // chunks + input[4] = Channel.of( + [[id: "1000GP", chr: "chr22"], []], + [[id: "1000GP", chr: "chr21"], []] + ) // map + input[5] = channel.of([ [id: "GRCh38"], [], [] ]).collect() + input[6] = 100 + input[7] = 10000 + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + + test("homo_sapiens - error empty joint - stub") { + options "-stub" + when { + params{ + quilt_args = "--seed=1" + } + workflow { + """ + bampath = Channel.of("NA12878.chr21_22.1X.bam").collectFile(name: 'bampath.txt', newLine: true) + bamname = Channel.of("MySample1").collectFile(name: 'bamname.txt', newLine: true) + ch_samples = channel.of([ + [id: "allid"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam.bai", checkIfExist:true) + ]) + input[0] = ch_samples.combine(bampath).combine(bamname) // input + input[1] = channel.of( + [[id: "1000GP", chr: "chr22"], [], []], + [[id: "1000GP", chr: "chr21"], [], []] + ) // hap legend + input[2] = channel.of( + [[id: "otherpanel", chr: "chr22"], []], // Wrong panel given + [[id: "1000GP", chr: "chr21"], []] + ) // posfile + input[3] = channel.of( + [[chr: "chr22", id: "1000GP"], "chr22", 16570065, 16592216], + [[chr: "chr22", id: "1000GP"], "chr22", 16592229, 16609999], + [[chr: "chr21", id: "1000GP"], "chr21", 16570065, 16592216], + [[chr: "chr21", id: "1000GP"], "chr21", 16592229, 16609999] + ) // chunks + input[4] = Channel.of( + [[id: "1000GP", chr: "chr22"], []], + [[id: "otherpanel", chr: "chr21"], []] // Wrong panel given + ) // map + input[5] = channel.of([ [id: "GRCh38"], [], [] ]).collect() + input[6] = 100 + input[7] = 10000 + """ + } + } + then { + assertAll( + { assert workflow.failed }, + { assert workflow.errorMessage.contains("ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input.") } + ) + } + } +} diff --git a/subworkflows/nf-core/bam_impute_quilt/tests/main.nf.test.snap b/subworkflows/nf-core/bam_impute_quilt/tests/main.nf.test.snap new file mode 100644 index 000000000000..459620b92605 --- /dev/null +++ b/subworkflows/nf-core/bam_impute_quilt/tests/main.nf.test.snap @@ -0,0 +1,181 @@ +{ + "homo_sapiens - empty channels - stub": { + "content": [ + { + "0": [ + [ + { + "id": "allid", + "chr": "chr21" + }, + "allid_chr21.ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "allid_chr21.ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "allid", + "chr": "chr22" + }, + "allid_chr22.ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "allid_chr22.ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,028db20d173980e1f8e5478b7f72e762", + "versions.yml:md5,92ae90beb980d97b831415fadfa6a075", + "versions.yml:md5,cb038a1f67a47a76d0e0a983cfd56789" + ], + "vcf_index": [ + [ + { + "id": "allid", + "chr": "chr21" + }, + "allid_chr21.ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "allid_chr21.ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "allid", + "chr": "chr22" + }, + "allid_chr22.ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "allid_chr22.ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,028db20d173980e1f8e5478b7f72e762", + "versions.yml:md5,92ae90beb980d97b831415fadfa6a075", + "versions.yml:md5,cb038a1f67a47a76d0e0a983cfd56789" + ] + }, + [ + { + "BAM_IMPUTE_QUILT:BCFTOOLS_INDEX": { + "bcftools": 1.22 + } + }, + { + "BAM_IMPUTE_QUILT:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_IMPUTE_QUILT:QUILT_QUILT": { + "r-base": "4.3.1", + "r-quilt": "1.0.5" + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-25T09:21:57.358363857" + }, + "Impute with quilt one individual, no renaming, posfile, no chunks, no map, no fasta": { + "content": [ + [ + [ + { + "id": "allid", + "chr": "chr22" + }, + "allid_chr22.ligate.vcf.gz", + "allid_chr22.ligate.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=903, phased=true, phasedAutodetect=false]", + [ + "NA12878" + ], + "98f97eac82da7e115c7965906e49b563" + ] + ], + [ + "versions.yml:md5,028db20d173980e1f8e5478b7f72e762", + "versions.yml:md5,92ae90beb980d97b831415fadfa6a075", + "versions.yml:md5,cb038a1f67a47a76d0e0a983cfd56789" + ], + [ + { + "BAM_IMPUTE_QUILT:BCFTOOLS_INDEX": { + "bcftools": 1.22 + } + }, + { + "BAM_IMPUTE_QUILT:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_IMPUTE_QUILT:QUILT_QUILT": { + "r-base": "4.3.1", + "r-quilt": "1.0.5" + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-27T11:40:27.108320329" + }, + "Impute with quilt two individual bam, renaming, posfile, chunks, map, no fasta": { + "content": [ + [ + [ + { + "id": "allid", + "chr": "chr21" + }, + "allid_chr21.ligate.vcf.gz", + "allid_chr21.ligate.vcf.gz.csi", + "VcfFile [chromosomes=[chr21], sampleCount=2, variantCount=836, phased=true, phasedAutodetect=false]", + [ + "MySample1", + "MySample2" + ], + "a1601c083256c8e3315c6dd128e4aea6" + ], + [ + { + "id": "allid", + "chr": "chr22" + }, + "allid_chr22.ligate.vcf.gz", + "allid_chr22.ligate.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=2, variantCount=903, phased=true, phasedAutodetect=false]", + [ + "MySample1", + "MySample2" + ], + "3a47675c78aacc7c0a385284160f4c07" + ] + ], + [ + { + "BAM_IMPUTE_QUILT:BCFTOOLS_INDEX": { + "bcftools": 1.22 + } + }, + { + "BAM_IMPUTE_QUILT:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_IMPUTE_QUILT:QUILT_QUILT": { + "r-base": "4.3.1", + "r-quilt": "1.0.5" + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-27T11:45:24.889532583" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/bam_impute_quilt/tests/nextflow.config b/subworkflows/nf-core/bam_impute_quilt/tests/nextflow.config new file mode 100644 index 000000000000..628ea54b1e8b --- /dev/null +++ b/subworkflows/nf-core/bam_impute_quilt/tests/nextflow.config @@ -0,0 +1,19 @@ +process { + withName: QUILT_QUILT { + cpus = 1 // Needed to have deterministic output for testing + ext.args = { "${params.quilt_args}" } + ext.prefix = { "${meta.id}_${meta.chr}_${meta.regionout}.quilt" } + tag = { "${meta.id} ${meta.chr} ${meta.regionout}" } + } + + withName: GLIMPSE2_LIGATE { + ext.prefix = { "${meta.id}_${meta.chr}.ligate" } + tag = { "${meta.id} ${meta.chr}" } + } + + withName: BCFTOOLS_INDEX { + ext.args = '--csi' + tag = { "${meta.id} ${meta.chr}" } + publishDir = [enabled: false] + } +} From 1f66a1ef3b9c30abe36ff411ba5371543e0da6b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Thu, 11 Dec 2025 12:31:00 +0100 Subject: [PATCH 65/83] Update glimpse2 imputation subworkflow (#9434) * Update glimpse2 sbwf * Update test * Update subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf Co-authored-by: Jonathan Manning * Update subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test Co-authored-by: Jonathan Manning * Add deprecation * Change ifEmpty --------- Co-authored-by: LouisLeNezet Co-authored-by: Jonathan Manning --- .../nf-core/glimpse2/splitreference/main.nf | 3 +- .../nf-core/glimpse2/splitreference/meta.yml | 5 - .../splitreference/tests/main.nf.test | 13 +- .../nf-core/bam_vcf_impute_glimpse2/main.nf | 123 ++++ .../meta.yml | 41 +- .../tests/main.nf.test | 461 +++++++++++++++ .../tests/main.nf.test.snap | 524 ++++++++++++++++++ .../tests/nextflow.config | 41 ++ .../multiple_impute_glimpse2/README.md | 4 + .../nf-core/multiple_impute_glimpse2/main.nf | 75 --- .../tests/main.nf.test | 173 ------ .../tests/main.nf.test.snap | 169 ------ .../tests/nextflow.config | 12 - 13 files changed, 1187 insertions(+), 457 deletions(-) create mode 100644 subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf rename subworkflows/nf-core/{multiple_impute_glimpse2 => bam_vcf_impute_glimpse2}/meta.yml (56%) create mode 100644 subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test create mode 100644 subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test.snap create mode 100644 subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/nextflow.config create mode 100644 subworkflows/nf-core/multiple_impute_glimpse2/README.md delete mode 100644 subworkflows/nf-core/multiple_impute_glimpse2/main.nf delete mode 100644 subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test delete mode 100644 subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test.snap delete mode 100644 subworkflows/nf-core/multiple_impute_glimpse2/tests/nextflow.config diff --git a/modules/nf-core/glimpse2/splitreference/main.nf b/modules/nf-core/glimpse2/splitreference/main.nf index 019072b8689d..0311e09dabc2 100644 --- a/modules/nf-core/glimpse2/splitreference/main.nf +++ b/modules/nf-core/glimpse2/splitreference/main.nf @@ -18,8 +18,7 @@ process GLIMPSE2_SPLITREFERENCE { 'biocontainers/glimpse-bio:2.0.1--h46b9e50_1' }" input: - tuple val(meta) , path(reference), path(reference_index), val(input_region), val(output_region) - tuple val(meta2), path(map) + tuple val(meta) , path(reference), path(reference_index), val(input_region), val(output_region), path(map) output: diff --git a/modules/nf-core/glimpse2/splitreference/meta.yml b/modules/nf-core/glimpse2/splitreference/meta.yml index 161dab0d5781..ed6b63ee03ad 100644 --- a/modules/nf-core/glimpse2/splitreference/meta.yml +++ b/modules/nf-core/glimpse2/splitreference/meta.yml @@ -42,11 +42,6 @@ input: type: string description: Target imputed region, excluding left and right buffers (e.g. chr20:1000000-2000000). pattern: "chrXX:leftBufferPosition-rightBufferPosition" - - - meta2: - type: map - description: | - Groovy Map containing genomic map information - e.g. `[ map:'GRCh38' ]` - map: type: file description: File containing the genetic map. diff --git a/modules/nf-core/glimpse2/splitreference/tests/main.nf.test b/modules/nf-core/glimpse2/splitreference/tests/main.nf.test index e95febde9a3c..9c353df2f643 100644 --- a/modules/nf-core/glimpse2/splitreference/tests/main.nf.test +++ b/modules/nf-core/glimpse2/splitreference/tests/main.nf.test @@ -20,9 +20,9 @@ nextflow_process { 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:16600000-16800000", - "chr22:16600000-16800000" + "chr22:16600000-16800000", + [] ] - input[1]= [[ id:'map'],[]] """ } } @@ -48,10 +48,7 @@ nextflow_process { 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:16600000-16800000", - "chr22:16600000-16800000" - ] - input[1]= [ - [ id:'map'], + "chr22:16600000-16800000", file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.glimpse.map", checkIfExists:true) ] """ @@ -80,9 +77,9 @@ nextflow_process { 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:16600000-16800000", - "chr22:16600000-16800000" + "chr22:16600000-16800000", + [] ] - input[1]= [[ id:'map'],[]] """ } } diff --git a/subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf b/subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf new file mode 100644 index 000000000000..db11d1f534b3 --- /dev/null +++ b/subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf @@ -0,0 +1,123 @@ +include { GLIMPSE2_CHUNK } from '../../../modules/nf-core/glimpse2/chunk/main' +include { GLIMPSE2_SPLITREFERENCE } from '../../../modules/nf-core/glimpse2/splitreference/main' +include { GLIMPSE2_PHASE } from '../../../modules/nf-core/glimpse2/phase/main' +include { GLIMPSE2_LIGATE } from '../../../modules/nf-core/glimpse2/ligate/main' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_1 } from '../../../modules/nf-core/bcftools/index/main.nf' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_2 } from '../../../modules/nf-core/bcftools/index/main.nf' + +workflow BAM_VCF_IMPUTE_GLIMPSE2 { + + take: + ch_input // channel (mandatory): [ meta, vcf, csi, list, infos ] + ch_ref // channel (mandatory): [ meta, vcf, csi, region ] + ch_chunks // channel (optional) : [ meta, regionin, regionout ] + ch_map // channel (optional) : [ meta, map ] + ch_fasta // channel (optional) : [ meta, fasta, index ] + chunk // val (optional) : boolean to activate/deactivate chunking step + chunk_model // val (optional) : model file for chunking + splitreference // val (optional) : boolean to activate/deactivate split reference step + + main: + + ch_versions = channel.empty() + + if ( chunk == true ){ + // Error if pre-defined chunks are provided when chunking is activated + ch_chunks + .filter { _meta, regionin, regionout -> regionin.size() == 0 && regionout.size() == 0 } + .ifEmpty { + error "ERROR: Cannot provide pre-defined chunks (regionin) when chunk=true. Please either set chunk=false to use provided chunks, or remove input chunks to enable automatic chunking." + } + + // Chunk reference panel + ch_ref_map = ch_ref + .combine(ch_map, by: 0) + GLIMPSE2_CHUNK ( ch_ref_map, chunk_model ) + ch_versions = ch_versions.mix( GLIMPSE2_CHUNK.out.versions.first() ) + + ch_chunks = GLIMPSE2_CHUNK.out.chunk_chr + .splitCsv(header: [ + 'ID', 'Chr', 'RegionBuf', 'RegionCnk', 'WindowCm', + 'WindowMb', 'NbTotVariants', 'NbComVariants' + ], sep: "\t", skip: 0) + .map { meta, it -> [meta, it["RegionBuf"], it["RegionCnk"]]} + } + + ch_chunks + .filter { _meta, regionin, regionout -> regionin.size() > 0 && regionout.size() > 0 } + .ifEmpty { error "ERROR: ch_chunks channel is empty. Please provide a valid channel or set chunk parameter to true." } + + if ( splitreference == true ) { + // Split reference panel in bin files + split_input = ch_ref + .combine(ch_chunks, by: 0) + .combine(ch_map, by: 0) + .map{ meta, ref, index, _region, regionin, regionout, gmap -> [ + meta + ["regionin": regionin, "regionout": regionout], + ref, index, regionin, regionout, gmap + ] } + + GLIMPSE2_SPLITREFERENCE( split_input ) + ch_versions = ch_versions.mix( GLIMPSE2_SPLITREFERENCE.out.versions.first() ) + + ch_chunks_panel_map = GLIMPSE2_SPLITREFERENCE.out.bin_ref + .map{ meta, bin_ref -> [ meta, [], [], bin_ref, [], [] ] } // Everything is provided by the bin file + } else { + ch_chunks_panel_map = ch_chunks + .combine(ch_ref, by:0) + .combine(ch_map, by:0) + .map{ meta, regionin, regionout, ref, ref_index, _region, gmap -> [ + meta + ["regionin": regionin, "regionout": regionout], + regionin, regionout, ref, ref_index, gmap + ] } + } + + ch_chunks_panel_map.ifEmpty{ + error "ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input." + } + + ch_phase_input = ch_input + .combine(ch_chunks_panel_map) + .map{ metaI, input, index, list, infos, metaCPM, regionin, regionout, panel, panel_index, gmap -> [ + metaI + metaCPM, // combined metadata + input, index, list, infos, // input files + regionin, regionout, // chunk regions + panel, panel_index, gmap // panel and map files + ] } + + // Impute with Glimpse2 + GLIMPSE2_PHASE(ch_phase_input, ch_fasta) + ch_versions = ch_versions.mix( GLIMPSE2_PHASE.out.versions.first() ) + + // Index phased file + BCFTOOLS_INDEX_1(GLIMPSE2_PHASE.out.phased_variants) + ch_versions = ch_versions.mix( BCFTOOLS_INDEX_1.out.versions.first() ) + + // Ligate all phased files in one and index it + ligate_input = GLIMPSE2_PHASE.out.phased_variants + .join( BCFTOOLS_INDEX_1.out.csi ) + .map{ meta, vcf, index -> + def keysToKeep = meta.keySet() - ['regionin', 'regionout'] + [ meta.subMap(keysToKeep), vcf, index ] + } + .groupTuple() + + GLIMPSE2_LIGATE( ligate_input ) + ch_versions = ch_versions.mix( GLIMPSE2_LIGATE.out.versions.first() ) + + BCFTOOLS_INDEX_2( GLIMPSE2_LIGATE.out.merged_variants ) + ch_versions = ch_versions.mix( BCFTOOLS_INDEX_2.out.versions.first() ) + + // Join imputed and index files + ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants + .join( + BCFTOOLS_INDEX_2.out.tbi + .mix(BCFTOOLS_INDEX_2.out.csi) + ) + + emit: + ch_chunks = ch_chunks // channel: [ val(meta), regionin, regionout ] + ch_vcf_index = ch_vcf_index // channel: [ val(meta), vcf, csi ] + + versions = ch_versions // channel: [ versions.yml ] +} diff --git a/subworkflows/nf-core/multiple_impute_glimpse2/meta.yml b/subworkflows/nf-core/bam_vcf_impute_glimpse2/meta.yml similarity index 56% rename from subworkflows/nf-core/multiple_impute_glimpse2/meta.yml rename to subworkflows/nf-core/bam_vcf_impute_glimpse2/meta.yml index 6fea6251cc15..41edf1abe46c 100644 --- a/subworkflows/nf-core/multiple_impute_glimpse2/meta.yml +++ b/subworkflows/nf-core/bam_vcf_impute_glimpse2/meta.yml @@ -1,4 +1,4 @@ -name: "multiple_impute_glimpse2" +name: "bam_vcf_impute_glimpse2" description: Impute VCF/BCF files, but also CRAM and BAM files with Glimpse2 keywords: - glimpse @@ -18,8 +18,9 @@ input: description: | Target dataset in CRAM, BAM or VCF/BCF format. Index file of the input file. + File containing the list of files to be imputed and their sample names (for CRAM/BAM input). File with sample names and ploidy information. - Structure: [ meta, file, index, txt ] + Structure: [ meta, file, index, bamlist, ploidy ] - ch_ref: type: file description: | @@ -28,10 +29,15 @@ input: Target region, usually a full chromosome (e.g. chr20:1000000-2000000 or chr20). The file could possibly be without GT field (for efficiency reasons a file containing only the positions is recommended). Structure: [ meta, vcf, csi, region ] + - ch_chunks: + type: string + description: | + Channel containing the chunking regions for each chromosome. + Structure: [ meta, region with buffer, region without buffer ] - ch_map: type: file description: | - File containing the genetic map. + Genetic map file for each chromosome. Structure: [ meta, gmap ] - ch_fasta: type: file @@ -39,21 +45,30 @@ input: Reference genome in fasta format. Reference genome index in fai format Structure: [ meta, fasta, fai ] + - chunk: + type: boolean + description: Whether to perform chunking of the input data before imputation. + - chunk_model: + type: string + description: | + Chunking model to use. + Options: "sequential", "recursive" + - splitreference: + type: boolean + description: Whether to split the reference panel and convert it to binary files before imputation. + output: - - chunk_chr: - type: file + - ch_chunks: + type: string description: | - Tab delimited output txt file containing buffer and imputation regions. - Structure: [meta, txt] - - merged_variants: + Channel containing the chunking regions for each chromosome. + Structure: [ meta, region with buffer, region without buffer ] + - ch_vcf_index: type: file description: | Output VCF/BCF file for the merged regions. - Phased information (HS field) is updated accordingly for the full region. - Structure: [ val(meta), bcf ] - - merged_variants_index: - type: file - description: Index file of the ligated phased variants files. + Index file of the output VCF/BCF file. + Structure: [ val(meta), variants, index ] - versions: type: file description: File containing software versions diff --git a/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test new file mode 100644 index 000000000000..15ed651546b1 --- /dev/null +++ b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test @@ -0,0 +1,461 @@ +nextflow_workflow { + + name "Test Workflow BAM_VCF_IMPUTE_GLIMPSE2" + config "./nextflow.config" + script "../main.nf" + workflow "BAM_VCF_IMPUTE_GLIMPSE2" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "bam_vcf_impute_glimpse2" + tag "subworkflows/bam_vcf_impute_glimpse2" + + tag "glimpse2/chunk" + tag "glimpse2/splitreference" + tag "glimpse2/phase" + tag "glimpse2/ligate" + tag "glimpse2" + tag "bcftools/index" + tag "bcftools" + + test("homo_sapiens - vcf no list and no sample, panel vcf region, no chunks, no map, no fasta, chunk recursive + splitreference") { + when { + workflow { + """ + input[0] = Channel.of([ + [id:'input_vcf'], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + [], [] + ]) // input + input[1] = Channel.of([ + [panel:'ref_panel', chr: "22"], + 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" + ]) // reference + input[2] = Channel.of([ + [panel: 'ref_panel', chr: "22"], + [], [] + ]) // chunks + input[3] = Channel.of([ + [panel: 'ref_panel', chr: "22"], + [] + ]) // map + input[4] = Channel.of([ + [id_genome:'ref_fasta'], [], [] + ]).collect() // genome + input[5] = true // perform chunking + input[6] = "recursive" // chunking model + input[7] = true // splitreference + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.ch_chunks, + workflow.out.ch_vcf_index.collect{[ + it[0], + path(it[1]).getFileName().toString(), + path(it[2]).getFileName().toString(), + path(it[1]).vcf.summary, + path(it[1]).vcf.header.getGenotypeSamples().sort(), + path(it[1]).vcf.variantsMD5 + ]}, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + test("homo_sapiens - vcf no list with sample, panel vcf region, chunks, map, no fasta, no chunking + splitreference") { + when { + workflow { + """ + sample = Channel.of('NA12878 2') + .collectFile(name: 'sampleinfos.txt') + input[0] = Channel.of([ + [id:'input_vcf'], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + [] // no list + ]) + .combine(sample) + input[1] = Channel.of([ + [panel: 'ref_panel', chr: "22"], + 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:16570065-16609999", + ]) + input[2] = Channel.of( + [[panel: 'ref_panel', chr: "22"], "chr22:16570065-16597215", "chr22:16570065-16592216"], + [[panel: 'ref_panel', chr: "22"], "chr22:16587172-16609999", "chr22:16592229-16609999"] + ) // chunks + input[3] = Channel.of([ + [panel: 'ref_panel', chr: "22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.glimpse.map", checkIfExists: true) + ]) // map + input[4] = Channel.of([ + [id_genome:'ref_fasta'], [], [] + ]).collect() // genome + input[5] = false // do not perform chunking + input[6] = "recursive" // chunking model + input[7] = true // splitreference + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.ch_chunks, + workflow.out.ch_vcf_index.collect{[ + it[0], + path(it[1]).getFileName().toString(), + path(it[2]).getFileName().toString(), + path(it[1]).vcf.summary, + path(it[1]).vcf.header.getGenotypeSamples().sort(), + path(it[1]).vcf.variantsMD5 + ]}, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + test("homo_sapiens - vcf no list with sample, panel vcf region, chunks, map, no fasta, no chunking + no splitreference") { + when { + workflow { + """ + sample = Channel.of('NA12878 2') + .collectFile(name: 'sampleinfos.txt') + input[0] = Channel.of([ + [id:'input_vcf'], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz.csi", checkIfExists: true), + [] // no list + ]) + .combine(sample) + input[1] = Channel.of([ + [panel: 'ref_panel', chr: "22"], + 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:16570065-16609999", + ]) + input[2] = Channel.of( + [[panel: 'ref_panel', chr: "22"], "chr22:16570065-16597215", "chr22:16570065-16592216"], + [[panel: 'ref_panel', chr: "22"], "chr22:16587172-16609999", "chr22:16592229-16609999"] + ) // chunks + input[3] = Channel.of([ + [panel: 'ref_panel', chr: "22"], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/phaseimpute/hum_data/reference_genome/GRCh38_chr22.glimpse.map", checkIfExists: true) + ]) // map + input[4] = Channel.of([ + [id_genome:'ref_fasta'], [], [] + ]).collect() // genome + input[5] = false // do not perform chunking + input[6] = "recursive" // chunking model + input[7] = false // no splitreference + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.ch_chunks, + workflow.out.ch_vcf_index.collect{[ + it[0], + path(it[1]).getFileName().toString(), + path(it[2]).getFileName().toString(), + path(it[1]).vcf.summary, + path(it[1]).vcf.header.getGenotypeSamples().sort(), + path(it[1]).vcf.variantsMD5 + ]}, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + test("homo_sapiens - bam no list and no sample, panel vcf region, no chunks, no map, no fasta, chunk sequential + splitreference") { + when { + workflow { + """ + input[0] = Channel.of([ + [id:'input_bam'], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam.bai", checkIfExists: true), + [], [] + ]) + input[1] = Channel.of([ + [panel: 'ref_panel', chr: "22"], + 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" + ]) + input[2] = Channel.of([ + [panel: 'ref_panel', chr: "22"], + [], [] + ]) // chunks + input[3] = Channel.of([ + [panel: 'ref_panel', chr: "22"], + [] + ]) // map + input[4] = Channel.of([ + [id_genome:'ref_fasta'], [], [] + ]).collect() // genome + input[5] = true // perform chunking + input[6] = "sequential" // chunking model + input[7] = true // splitreference + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.ch_chunks, + workflow.out.ch_vcf_index.collect{[ + it[0], + path(it[1]).getFileName().toString(), + path(it[2]).getFileName().toString(), + path(it[1]).vcf.summary, + path(it[1]).vcf.header.getGenotypeSamples().sort(), + path(it[1]).vcf.variantsMD5 + ]}, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + test("homo_sapiens - bam list and sample, panel vcf region, chunks, map, no fasta, no chunking + splitreference") { + when { + workflow { + """ + bamlist = Channel.of( + "NA12878.chr21_22.1X.bam\tSample1", + "NA19401.chr21_22.1X.bam\tSample2" + ).collectFile(name: 'bamlist.txt', newLine: true) + sample = Channel.of('NA12878 2') + .collectFile(name: 'sampleinfos.txt') + input[0] = Channel.of([ + [id: "allid"], [ + 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/NA19401.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/illumina/bam/NA19401.chr21_22.1X.bam.bai", checkIfExists: true) + ] + ]).combine(bamlist).combine(sample) + input[1] = Channel.of([ + [panel: 'ref_panel', chr: "22"], + 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" + ],[ + [panel: 'ref_panel', chr: "21"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz", checkIfExists:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz.csi", checkIfExists:true), + "chr21" + ]) // reference + input[2] = Channel.of( + [[panel: 'ref_panel', chr: "22"], "chr22:16570065-16597215", "chr22:16570065-16592216"], + [[panel: 'ref_panel', chr: "22"], "chr22:16587172-16609999", "chr22:16592229-16609999"], + [[panel: 'ref_panel', chr: "21"], "chr21:16570065-16597215", "chr21:16570065-16592216"], + [[panel: 'ref_panel', chr: "21"], "chr21:16587172-16609999", "chr21:16592229-16609999"] + ) // chunks + input[3] = Channel.of([ + [panel: 'ref_panel', chr: "22"], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.glimpse.map", checkIfExists:true) + ],[ + [panel: 'ref_panel', chr: "21"], file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr21.glimpse.map", checkIfExists:true) + ]) // map + input[4] = Channel.of([ + [id_genome:'ref_fasta'], [], [] + ]).collect() // genome + input[5] = false // perform chunking + input[6] = "sequential" // chunking model + input[7] = true // splitreference + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.ch_chunks, + workflow.out.ch_vcf_index.collect{[ + it[0], + path(it[1]).getFileName().toString(), + path(it[2]).getFileName().toString(), + path(it[1]).vcf.summary, + path(it[1]).vcf.header.getGenotypeSamples().sort(), + path(it[1]).vcf.variantsMD5 + ]}, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + test("homo_sapiens - empty channels, chunk sequential + splitreference - stub") { + options "-stub" + when { + workflow { + """ + input[0] = Channel.of([ + [id: "allid"], + 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([ + [panel: 'ref_panel', chr: "22"], [], [], "chr22" + ],[ + [panel: 'ref_panel', chr: "21"], [], [], "chr21" + ]) // reference + input[2] = Channel.of( + [[panel: 'ref_panel', chr: "22"], [], []], + [[panel: 'ref_panel', chr: "21"], [], []] + ) // chunks + input[3] = Channel.of([ + [panel: 'ref_panel', chr: "22"], [] + ],[ + [panel: 'ref_panel', chr: "21"], [] + ]) // map + input[4] = Channel.of([ + [id_genome:'ref_fasta'], [], [] + ]).collect() // genome + input[5] = true // perform chunking + input[6] = "sequential" // chunking model + input[7] = true // splitreference + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + + test("homo_sapiens - error chunks provided and chunk is true") { + options "-stub" + when { + workflow { + """ + input[0] = Channel.of([ [id: "allid"], [], [], [], [] ]) + input[1] = Channel.of([ + [panel: 'ref_panel', chr: "22"], [], [], "chr22" + ],[ + [panel: 'ref_panel', chr: "21"], [], [], "chr21" + ]) // reference + input[2] = Channel.of( + [[panel: 'ref_panel', chr: "22"], "chr22:16570065-16597215", "chr22:16570065-16592216"], + [[panel: 'ref_panel', chr: "22"], "chr22:16587172-16609999", "chr22:16592229-16609999"], + [[panel: 'ref_panel', chr: "21"], "chr21:16570065-16597215", "chr21:16570065-16592216"], + [[panel: 'ref_panel', chr: "21"], "chr21:16587172-16609999", "chr21:16592229-16609999"] + ) // chunks + input[3] = Channel.of([ + [panel: 'ref_panel', chr: "22"], [] + ],[ + [panel: 'ref_panel', chr: "21"], [] + ]) // map + input[4] = Channel.of([ + [id_genome:'ref_fasta'], [], [] + ]).collect() // genome + input[5] = true // perform chunking + input[6] = "sequential" // chunking model + input[7] = true // splitreference + """ + } + } + then { + assertAll( + { assert workflow.failed }, + { assert workflow.errorMessage.contains("ERROR: Cannot provide pre-defined chunks (regionin) when chunk=true. Please either set chunk=false to use provided chunks, or remove input chunks to enable automatic chunking.") } + ) + } + } + + test("homo_sapiens - error no chunks provided and chunk is false") { + options "-stub" + when { + workflow { + """ + input[0] = Channel.of([ [id: "allid"], [], [], [], [] ]) + input[1] = Channel.of([ + [panel: 'ref_panel', chr: "22"], [], [], "chr22" + ],[ + [panel: 'ref_panel', chr: "21"], [], [], "chr21" + ]) // reference + input[2] = Channel.of( + [[panel: 'ref_panel', chr: "22"], [], []], + [[panel: 'ref_panel', chr: "21"], [], []] + ) // chunks + input[3] = Channel.of([ + [panel: 'ref_panel', chr: "22"], [] + ],[ + [panel: 'ref_panel', chr: "21"], [] + ]) // map + input[4] = Channel.of([ + [id_genome:'ref_fasta'], [], [] + ]).collect() // genome + input[5] = false // perform chunking + input[6] = "sequential" // chunking model + input[7] = true // splitreference + """ + } + } + then { + assertAll( + { assert workflow.failed }, + { assert workflow.errorMessage.contains("ERROR: ch_chunks channel is empty. Please provide a valid channel or set chunk parameter to true.") } + ) + } + } + + test("homo_sapiens - error empty joint") { + options "-stub" + when { + workflow { + """ + input[0] = Channel.of([ + [id: "allid"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/NA12878.chr22.1X.bam.bai", checkIfExists: true), + [], [] + ]) + input[1] = Channel.of([ + [panel: 'ref_panel', chr: "22"], [], [], "chr22" + ],[ + [panel: 'ref_panel', chr: "21"], [], [], "chr21" + ]) // reference + input[2] = Channel.of( + [[panel: 'ref_panel 2', chr: "22"], "chr22:16570065-16597215", "chr22:16570065-16592216"], + [[panel: 'ref_panel', chr: "21"], "chr21:16570065-16597215", "chr21:16570065-16592216"] + ) // chunks + input[3] = Channel.of([ + [panel: 'ref_panel', chr: "22"], [] + ],[ + [panel: 'ref_panel 1', chr: "21"], [] + ]) // map + input[4] = Channel.of([ + [id_genome:'ref_fasta'], [], [] + ]).collect() // genome + input[5] = false // perform chunking + input[6] = "sequential" // chunking model + input[7] = false // splitreference + """ + } + } + then { + assertAll( + { assert workflow.failed }, + { assert workflow.errorMessage.contains("ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input.") } + ) + } + } +} diff --git a/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test.snap b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test.snap new file mode 100644 index 000000000000..d7e3e862c1e0 --- /dev/null +++ b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test.snap @@ -0,0 +1,524 @@ +{ + "homo_sapiens - vcf no list and no sample, panel vcf region, no chunks, no map, no fasta, chunk recursive + splitreference": { + "content": [ + [ + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16570065-16609999", + "chr22:16570065-16592222" + ], + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16570065-16609999", + "chr22:16592223-16609999" + ] + ], + [ + [ + { + "id": "input_vcf", + "panel": "ref_panel", + "chr": "22" + }, + "input_vcf_22.vcf.gz", + "input_vcf_22.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=903, phased=true, phasedAutodetect=false]", + [ + "NA12878" + ], + "b9ccc0359ccca0714fca43367538de47" + ] + ], + [ + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_CHUNK": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_PHASE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_2": { + "bcftools": 1.22 + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_1": { + "bcftools": 1.22 + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_SPLITREFERENCE": { + "glimpse2": "2.0.0" + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-21T12:07:17.825740137" + }, + "homo_sapiens - bam no list and no sample, panel vcf region, no chunks, no map, no fasta, chunk sequential + splitreference": { + "content": [ + [ + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:1-16609999", + "chr22:1-16590520" + ], + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16570065-1248956422", + "chr22:16590521-1248956422" + ] + ], + [ + [ + { + "id": "input_bam", + "panel": "ref_panel", + "chr": "22" + }, + "input_bam_22.vcf.gz", + "input_bam_22.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=903, phased=true, phasedAutodetect=true]", + [ + "NA12878.chr22.1X" + ], + "661a9923af273601dbf0e7a3a666ebd0" + ] + ], + [ + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_CHUNK": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_PHASE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_2": { + "bcftools": 1.22 + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_1": { + "bcftools": 1.22 + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_SPLITREFERENCE": { + "glimpse2": "2.0.0" + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-21T12:08:29.707313034" + }, + "homo_sapiens - empty channels, chunk sequential + splitreference - stub": { + "content": [ + { + "0": [ + [ + { + "panel": "ref_panel", + "chr": "21" + }, + "0", + "0" + ], + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "0", + "0" + ] + ], + "1": [ + [ + { + "id": "allid", + "panel": "ref_panel", + "chr": "21" + }, + "allid_21.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "allid_21.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "allid", + "panel": "ref_panel", + "chr": "22" + }, + "allid_22.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "allid_22.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,302281bbff76712870c031340d3819ff", + "versions.yml:md5,3500318c881e3f24e9dd2fddc593142a", + "versions.yml:md5,9422ca169a15fd68878396c2837bc185", + "versions.yml:md5,c6ff81aa44fb2fdcc08db6062731d0d9", + "versions.yml:md5,cb51e18b4296c3791ade5f6f2737bd24", + "versions.yml:md5,ed6ebcf6ca30c2cdc39ec1dd535a2695" + ], + "ch_chunks": [ + [ + { + "panel": "ref_panel", + "chr": "21" + }, + "0", + "0" + ], + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "0", + "0" + ] + ], + "ch_vcf_index": [ + [ + { + "id": "allid", + "panel": "ref_panel", + "chr": "21" + }, + "allid_21.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "allid_21.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "allid", + "panel": "ref_panel", + "chr": "22" + }, + "allid_22.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "allid_22.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,302281bbff76712870c031340d3819ff", + "versions.yml:md5,3500318c881e3f24e9dd2fddc593142a", + "versions.yml:md5,9422ca169a15fd68878396c2837bc185", + "versions.yml:md5,c6ff81aa44fb2fdcc08db6062731d0d9", + "versions.yml:md5,cb51e18b4296c3791ade5f6f2737bd24", + "versions.yml:md5,ed6ebcf6ca30c2cdc39ec1dd535a2695" + ] + }, + [ + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_CHUNK": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_PHASE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_2": { + "bcftools": 1.22 + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_1": { + "bcftools": 1.22 + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_SPLITREFERENCE": { + "glimpse2": "2.0.0" + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-21T12:10:17.321588787" + }, + "homo_sapiens - vcf no list with sample, panel vcf region, chunks, map, no fasta, no chunking + no splitreference": { + "content": [ + [ + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16570065-16597215", + "chr22:16570065-16592216" + ], + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16587172-16609999", + "chr22:16592229-16609999" + ] + ], + [ + [ + { + "id": "input_vcf", + "panel": "ref_panel", + "chr": "22" + }, + "input_vcf_22.vcf.gz", + "input_vcf_22.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=903, phased=true, phasedAutodetect=false]", + [ + "NA12878" + ], + "a0d696cbdb219c168b6d54fc28c5f7dd" + ] + ], + [ + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_PHASE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_2": { + "bcftools": 1.22 + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_1": { + "bcftools": 1.22 + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-21T12:08:13.222110779" + }, + "homo_sapiens - vcf no list with sample, panel vcf region, chunks, map, no fasta, no chunking + splitreference": { + "content": [ + [ + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16570065-16597215", + "chr22:16570065-16592216" + ], + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16587172-16609999", + "chr22:16592229-16609999" + ] + ], + [ + [ + { + "id": "input_vcf", + "panel": "ref_panel", + "chr": "22" + }, + "input_vcf_22.vcf.gz", + "input_vcf_22.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=903, phased=true, phasedAutodetect=false]", + [ + "NA12878" + ], + "a0d696cbdb219c168b6d54fc28c5f7dd" + ] + ], + [ + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_PHASE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_2": { + "bcftools": 1.22 + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_1": { + "bcftools": 1.22 + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_SPLITREFERENCE": { + "glimpse2": "2.0.0" + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-11-21T12:07:58.812913099" + }, + "homo_sapiens - bam list and sample, panel vcf region, chunks, map, no fasta, no chunking + splitreference": { + "content": [ + [ + [ + { + "panel": "ref_panel", + "chr": "21" + }, + "chr21:16570065-16597215", + "chr21:16570065-16592216" + ], + [ + { + "panel": "ref_panel", + "chr": "21" + }, + "chr21:16587172-16609999", + "chr21:16592229-16609999" + ], + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16570065-16597215", + "chr22:16570065-16592216" + ], + [ + { + "panel": "ref_panel", + "chr": "22" + }, + "chr22:16587172-16609999", + "chr22:16592229-16609999" + ] + ], + [ + [ + { + "id": "allid", + "panel": "ref_panel", + "chr": "21" + }, + "allid_21.vcf.gz", + "allid_21.vcf.gz.csi", + "VcfFile [chromosomes=[chr21], sampleCount=2, variantCount=836, phased=true, phasedAutodetect=true]", + [ + "Sample1", + "Sample2" + ], + "56a7bd192123c52ea77f8b3a59e50342" + ], + [ + { + "id": "allid", + "panel": "ref_panel", + "chr": "22" + }, + "allid_22.vcf.gz", + "allid_22.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=2, variantCount=903, phased=true, phasedAutodetect=true]", + [ + "Sample1", + "Sample2" + ], + "13cdb23c1074393f9fe53feae397a3df" + ] + ], + [ + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_PHASE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_2": { + "bcftools": 1.22 + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_1": { + "bcftools": 1.22 + } + }, + { + "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_SPLITREFERENCE": { + "glimpse2": "2.0.0" + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-08T19:39:08.135355223" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/nextflow.config b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/nextflow.config new file mode 100644 index 000000000000..9cd201b85a2a --- /dev/null +++ b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/nextflow.config @@ -0,0 +1,41 @@ +process { + withName: "GLIMPSE2_CHUNK" { + ext.prefix = { "${meta.panel}_${meta.chr}" } + tag = { "${meta.panel} ${meta.chr}}" } + ext.args = [ + "--window-mb 0.01", + "--window-cm 0.01", + "--window-count 200", + "--buffer-mb 0.005", + "--buffer-cm 0.005", + "--buffer-count 30", + "--seed 1" + ].join(' ') + } + + withName: "GLIMPSE2_SPLITREFERENCE" { + ext.prefix = { "${meta.panel}_${meta.chr}_${meta.regionout}" } + tag = { "${meta.panel} ${meta.chr} ${meta.regionout}" } + ext.args = "--seed 1" + } + + withName: "GLIMPSE2_PHASE" { + ext.prefix = { "${meta.id}_${meta.chr}_${meta.regionout}" } + tag = { "${meta.id} ${meta.chr} ${meta.regionout}" } + cpus = 1 + ext.args = "--keep-monomorphic-ref-sites --seed 1" + } + + withName: "BCFTOOLS_INDEX_1" { + tag = { "${meta.id} ${meta.chr} ${meta.regionout}" } + } + + withName: "GLIMPSE2_LIGATE" { + ext.prefix = { "${meta.id}_${meta.chr}" } + tag = { "${meta.id} ${meta.chr}" } + } + + withName: "BCFTOOLS_INDEX_2" { + tag = { "${meta.id} ${meta.chr}" } + } +} diff --git a/subworkflows/nf-core/multiple_impute_glimpse2/README.md b/subworkflows/nf-core/multiple_impute_glimpse2/README.md new file mode 100644 index 000000000000..695001a4f198 --- /dev/null +++ b/subworkflows/nf-core/multiple_impute_glimpse2/README.md @@ -0,0 +1,4 @@ +> [!WARNING] +> This subworkflow has been deprecated. Please use `nf-core/modules/subworkflows/bam_vcf_impute_glimpse2` +> +> **Reason:** Subworkflow naming rules were introduced necessitating this move, see https://nf-co.re/docs/guidelines/components/subworkflows#name-format-of-subworkflow-files diff --git a/subworkflows/nf-core/multiple_impute_glimpse2/main.nf b/subworkflows/nf-core/multiple_impute_glimpse2/main.nf deleted file mode 100644 index c9c0022beacc..000000000000 --- a/subworkflows/nf-core/multiple_impute_glimpse2/main.nf +++ /dev/null @@ -1,75 +0,0 @@ -include { GLIMPSE2_CHUNK } from '../../../modules/nf-core/glimpse2/chunk/main' -include { GLIMPSE2_SPLITREFERENCE } from '../../../modules/nf-core/glimpse2/splitreference/main' -include { GLIMPSE2_PHASE } from '../../../modules/nf-core/glimpse2/phase/main' -include { GLIMPSE2_LIGATE } from '../../../modules/nf-core/glimpse2/ligate/main' -include { BCFTOOLS_INDEX as INDEX_PHASE } from '../../../modules/nf-core/bcftools/index/main.nf' -include { BCFTOOLS_INDEX as INDEX_LIGATE } from '../../../modules/nf-core/bcftools/index/main.nf' - -workflow MULTIPLE_IMPUTE_GLIMPSE2 { - - take: - ch_input // channel (mandatory): [ meta, vcf, csi, infos ] - ch_ref // channel (mandatory): [ meta, vcf, csi, region ] - ch_map // channel (optional) : [ meta, map ] - ch_fasta // channel (optional) : [ meta, fasta, index ] - chunk_model // string: model used to chunk the reference panel - - main: - - ch_versions = channel.empty() - - // Chunk reference panel - ch_ref_map = ch_ref.combine(ch_map, by: 0) - GLIMPSE2_CHUNK ( ch_ref_map, chunk_model ) - ch_versions = ch_versions.mix( GLIMPSE2_CHUNK.out.versions.first() ) - - chunk_output = GLIMPSE2_CHUNK.out.chunk_chr - .splitCsv(header: [ - 'ID', 'Chr', 'RegionBuf', 'RegionCnk', 'WindowCm', - 'WindowMb', 'NbTotVariants', 'NbComVariants' - ], sep: "\t", skip: 0) - .map { meta, it -> [meta, it["RegionBuf"], it["RegionCnk"]]} - - // Split reference panel in bin files - split_input = ch_ref.map{ meta, ref, index, _region -> [meta, ref, index]} - .combine(chunk_output, by: 0) - - GLIMPSE2_SPLITREFERENCE( split_input, ch_map ) - ch_versions = ch_versions.mix( GLIMPSE2_SPLITREFERENCE.out.versions.first() ) - - phase_input = ch_input.combine( GLIMPSE2_SPLITREFERENCE.out.bin_ref ) - .map{ input_meta, input_file, input_index, input_infos, - _panel_meta, panel_bin -> - [input_meta, input_file, input_index, [], input_infos, - [], [], panel_bin, [], []] - }/* Remove unnecessary meta maps - add null index as we use a bin file, - add null value for input and output region as we use a bin file */ - - // Phase input files for each reference bin files + indexing - GLIMPSE2_PHASE ( phase_input, ch_fasta ) // [meta, vcf, index, sample_infos, regionin, regionout, regionindex, ref, ref_index, map], [ meta, fasta, index ] - ch_versions = ch_versions.mix( GLIMPSE2_PHASE.out.versions.first() ) - - INDEX_PHASE ( GLIMPSE2_PHASE.out.phased_variants ) - ch_versions = ch_versions.mix( INDEX_PHASE.out.versions.first() ) - - // Ligate all phased files in one and index it - ligate_input = GLIMPSE2_PHASE.out.phased_variants - .groupTuple() - .combine( INDEX_PHASE.out.csi - .groupTuple() - .collect(), by: 0 ) - - GLIMPSE2_LIGATE ( ligate_input ) - ch_versions = ch_versions.mix( GLIMPSE2_LIGATE.out.versions.first() ) - - INDEX_LIGATE ( GLIMPSE2_LIGATE.out.merged_variants ) - ch_versions = ch_versions.mix( INDEX_LIGATE.out.versions.first() ) - - emit: - chunk_chr = GLIMPSE2_CHUNK.out.chunk_chr // channel: [ val(meta), txt ] - merged_variants = GLIMPSE2_LIGATE.out.merged_variants // channel: [ val(meta), bcf ] - merged_variants_index = INDEX_LIGATE.out.csi // channel: [ val(meta), csi ] - - versions = ch_versions // channel: [ versions.yml ] -} diff --git a/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test b/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test deleted file mode 100644 index 989bdb8a1ca7..000000000000 --- a/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test +++ /dev/null @@ -1,173 +0,0 @@ -nextflow_workflow { - - name "Test Workflow MULTIPLE_IMPUTE_GLIMPSE2" - config "./nextflow.config" - script "../main.nf" - workflow "MULTIPLE_IMPUTE_GLIMPSE2" - - tag "subworkflows" - tag "subworkflows_nfcore" - tag "multiple_impute_glimpse2" - tag "subworkflows/multiple_impute_glimpse2" - - tag "glimpse2/chunk" - tag "glimpse2/splitreference" - tag "glimpse2/phase" - tag "glimpse2/ligate" - tag "glimpse2" - tag "bcftools/index" - tag "bcftools" - - test("homo_sapiens - vcf [] - panel vcf region - [] - [] - recursive") { - when { - workflow { - """ - input[0] = Channel.of([ - [id:'input_vcf'], - 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] = Channel.of([ - [id:'ref_panel', chr: "22"], - 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", - ]) - input[2] = Channel.of([ - [id: 'ref_panel', chr: "22"], - [] - ]) - input[3] = Channel.of([[id:'ref_fasta'], [], []]).collect() - input[4] = "recursive" - """ - } - } - then { - assertAll( - { assert workflow.success }, - { assert snapshot( - workflow.out.chunk_chr, - workflow.out.merged_variants.collect{ path(it[1]).vcf.variantsMD5}, - file(workflow.out.merged_variants_index[0][1]).name, // The .csi index file sometimes change - workflow.out.versions - ).match() } - ) - } - } - test("homo_sapiens - vcf sample - panel vcf - [] - [] - recursive") { - when { - workflow { - """ - sample = Channel.of('NA12878 2') - .collectFile(name: 'sampleinfos.txt') - input[0] = Channel.of([ - [id:'input_vcf'], - 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), - ]).combine(sample) - input[1] = Channel.of([ - [id:'ref_panel', chr: "22"], - 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:16570065-16609999", - ]) - input[2] = Channel.of([ - [id:'ref_panel', chr: "22"], - [] - ]).collect() - input[3] = Channel.of([ - [id:'ref_fasta'], - [], - [] - ]).collect() - input[4] = "recursive" - """ - } - } - then { - assertAll( - { assert workflow.success }, - { assert snapshot( - workflow.out.chunk_chr, - workflow.out.merged_variants.collect{ path(it[1]).vcf.variantsMD5}, - file(workflow.out.merged_variants_index[0][1]).name, - workflow.out.versions - ).match() } - ) - } - } - test("homo_sapiens - bam [] - panel vcf - [] - [] - sequential") { - when { - workflow { - """ - input[0] = Channel.of([ - [id:'input_bam'], - 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:'ref_panel', chr: "22"], - 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", - ]) - input[2] = Channel.of([ - [id: 'ref_panel', chr: "22"], - [] - ]) - input[3] = Channel.of([[id:'ref_fasta'], [], []]).collect() - input[4] = "sequential" - """ - } - } - then { - assertAll( - { assert workflow.success }, - { assert snapshot( - workflow.out.chunk_chr, - workflow.out.merged_variants.collect{ path(it[1]).vcf.variantsMD5}, - file(workflow.out.merged_variants_index[0][1]).name, - workflow.out.versions - ).match() } - ) - } - } - test("homo_sapiens - bam [] - panel vcf - [] - [] - sequential -- stub") { - tag "stub" - options "-stub" - when { - workflow { - """ - input[0] = input[0] = Channel.of([ - [id:'input_bam'], - 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:'ref_panel', chr: "22"], - 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", - ]) - input[2] = Channel.of([ - [id: 'ref_panel', chr: "22"], - [] - ]) - input[3] = Channel.of([[id:'ref_fasta'], [], []]).collect() - input[4] = "sequential" - """ - } - } - then { - assertAll( - { assert workflow.success }, - { assert snapshot( - workflow.out - ).match() } - ) - } - } -} diff --git a/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test.snap b/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test.snap deleted file mode 100644 index 232c67643f96..000000000000 --- a/subworkflows/nf-core/multiple_impute_glimpse2/tests/main.nf.test.snap +++ /dev/null @@ -1,169 +0,0 @@ -{ - "homo_sapiens - vcf sample - panel vcf - [] - [] - recursive": { - "content": [ - [ - [ - { - "id": "ref_panel", - "chr": "22" - }, - "ref_panel.txt:md5,c363e235162ca0f7d22e5604c192e256" - ] - ], - [ - "9794b042f8c50f7d9a4dbe448de5ed5e" - ], - "input_vcf.vcf.gz.csi", - [ - "versions.yml:md5,048d5415737cdc568fcc4fbdc5df11e2", - "versions.yml:md5,1301ab7e8d92b232e306aef24d94e252", - "versions.yml:md5,1362d3f6834c21239d705f550b11c2af", - "versions.yml:md5,2373902d5432eba6898c90d4c4685f90", - "versions.yml:md5,642ed64b13825472557113ba2e4b1566", - "versions.yml:md5,e81cfbe9cf12832b8312f966b6c9beb1" - ] - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.0" - }, - "timestamp": "2025-11-27T11:11:34.893641629" - }, - "homo_sapiens - bam [] - panel vcf - [] - [] - sequential": { - "content": [ - [ - [ - { - "id": "ref_panel", - "chr": "22" - }, - "ref_panel.txt:md5,4714831df331b665e634eb1a86a84156" - ] - ], - [ - "49df7da6c9745ba9a86112193ff172a9" - ], - "input_bam.vcf.gz.csi", - [ - "versions.yml:md5,048d5415737cdc568fcc4fbdc5df11e2", - "versions.yml:md5,1301ab7e8d92b232e306aef24d94e252", - "versions.yml:md5,1362d3f6834c21239d705f550b11c2af", - "versions.yml:md5,2373902d5432eba6898c90d4c4685f90", - "versions.yml:md5,642ed64b13825472557113ba2e4b1566", - "versions.yml:md5,e81cfbe9cf12832b8312f966b6c9beb1" - ] - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.0" - }, - "timestamp": "2025-11-26T21:19:09.9592341" - }, - "homo_sapiens - bam [] - panel vcf - [] - [] - sequential -- stub": { - "content": [ - { - "0": [ - [ - { - "id": "ref_panel", - "chr": "22" - }, - "ref_panel.txt:md5,2fc283dec1e755af6119f2ef6485ceee" - ] - ], - "1": [ - [ - { - "id": "input_bam" - }, - "input_bam.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "2": [ - [ - { - "id": "input_bam" - }, - "input_bam.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - "versions.yml:md5,048d5415737cdc568fcc4fbdc5df11e2", - "versions.yml:md5,1301ab7e8d92b232e306aef24d94e252", - "versions.yml:md5,1362d3f6834c21239d705f550b11c2af", - "versions.yml:md5,2373902d5432eba6898c90d4c4685f90", - "versions.yml:md5,642ed64b13825472557113ba2e4b1566", - "versions.yml:md5,e81cfbe9cf12832b8312f966b6c9beb1" - ], - "chunk_chr": [ - [ - { - "id": "ref_panel", - "chr": "22" - }, - "ref_panel.txt:md5,2fc283dec1e755af6119f2ef6485ceee" - ] - ], - "merged_variants": [ - [ - { - "id": "input_bam" - }, - "input_bam.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "merged_variants_index": [ - [ - { - "id": "input_bam" - }, - "input_bam.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions": [ - "versions.yml:md5,048d5415737cdc568fcc4fbdc5df11e2", - "versions.yml:md5,1301ab7e8d92b232e306aef24d94e252", - "versions.yml:md5,1362d3f6834c21239d705f550b11c2af", - "versions.yml:md5,2373902d5432eba6898c90d4c4685f90", - "versions.yml:md5,642ed64b13825472557113ba2e4b1566", - "versions.yml:md5,e81cfbe9cf12832b8312f966b6c9beb1" - ] - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" - }, - "timestamp": "2025-09-15T07:30:40.001652658" - }, - "homo_sapiens - vcf [] - panel vcf region - [] - [] - recursive": { - "content": [ - [ - [ - { - "id": "ref_panel", - "chr": "22" - }, - "ref_panel.txt:md5,c363e235162ca0f7d22e5604c192e256" - ] - ], - [ - "9794b042f8c50f7d9a4dbe448de5ed5e" - ], - "input_vcf.vcf.gz.csi", - [ - "versions.yml:md5,048d5415737cdc568fcc4fbdc5df11e2", - "versions.yml:md5,1301ab7e8d92b232e306aef24d94e252", - "versions.yml:md5,1362d3f6834c21239d705f550b11c2af", - "versions.yml:md5,2373902d5432eba6898c90d4c4685f90", - "versions.yml:md5,642ed64b13825472557113ba2e4b1566", - "versions.yml:md5,e81cfbe9cf12832b8312f966b6c9beb1" - ] - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.6" - }, - "timestamp": "2025-09-15T07:29:48.094975599" - } -} \ No newline at end of file diff --git a/subworkflows/nf-core/multiple_impute_glimpse2/tests/nextflow.config b/subworkflows/nf-core/multiple_impute_glimpse2/tests/nextflow.config deleted file mode 100644 index e89bc79602dd..000000000000 --- a/subworkflows/nf-core/multiple_impute_glimpse2/tests/nextflow.config +++ /dev/null @@ -1,12 +0,0 @@ -process { - withName: "GLIMPSE2_CHUNK" { - ext.args = [ - "--window-mb 0.01", - "--window-cm 0.01", - "--window-count 200", - "--buffer-mb 0.005", - "--buffer-cm 0.005", - "--buffer-count 30" - ].join(' ') - } -} From e23f119d08a5cae2b9990771072e5be53bb7cf6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Thu, 11 Dec 2025 14:07:38 +0100 Subject: [PATCH 66/83] Add `BEAGLE5` imputation subworkflow (#9550) * Update glimpse2 sbwf * Update test * Add region to beagle5 * Add subworkflow * Fix linting * Fix linting * Fix linting * Update subworkflows/nf-core/vcf_impute_beagle5/main.nf Co-authored-by: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> * Add comment * Update grouping and test * Remove tag * Revert change glimpse2 reference * Revert change glimpse2 sbwf * Revert change glimpse2 sbwf * Revert change glimpse2 sbwf --------- Co-authored-by: LouisLeNezet Co-authored-by: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> --- modules/nf-core/beagle5/beagle/main.nf | 10 +- modules/nf-core/beagle5/beagle/meta.yml | 4 + .../nf-core/beagle5/beagle/tests/main.nf.test | 22 +- .../beagle5/beagle/tests/nextflow.config | 5 - .../nf-core/vcf_impute_beagle5/main.nf | 116 +++++++++ .../nf-core/vcf_impute_beagle5/meta.yml | 100 ++++++++ .../vcf_impute_beagle5/tests/main.nf.test | 237 ++++++++++++++++++ .../tests/main.nf.test.snap | 206 +++++++++++++++ .../vcf_impute_beagle5/tests/nextflow.config | 25 ++ 9 files changed, 699 insertions(+), 26 deletions(-) delete mode 100644 modules/nf-core/beagle5/beagle/tests/nextflow.config create mode 100644 subworkflows/nf-core/vcf_impute_beagle5/main.nf create mode 100644 subworkflows/nf-core/vcf_impute_beagle5/meta.yml create mode 100644 subworkflows/nf-core/vcf_impute_beagle5/tests/main.nf.test create mode 100644 subworkflows/nf-core/vcf_impute_beagle5/tests/main.nf.test.snap create mode 100644 subworkflows/nf-core/vcf_impute_beagle5/tests/nextflow.config diff --git a/modules/nf-core/beagle5/beagle/main.nf b/modules/nf-core/beagle5/beagle/main.nf index 93ffbc6a3a98..e66c9e40b019 100644 --- a/modules/nf-core/beagle5/beagle/main.nf +++ b/modules/nf-core/beagle5/beagle/main.nf @@ -8,7 +8,9 @@ process BEAGLE5_BEAGLE { 'biocontainers/beagle:5.5_27Feb25.75f--hdfd78af_0' }" input: - tuple val(meta), path(vcf), path(vcf_index), path(refpanel), path(refpanel_index), path(genmap), path(exclsamples), path(exclmarkers) + // Including `val(region)` to prevent errors with multi-chromosome VCFs and single-chromosome reference panels. + // This enhances clarity and simplifies implementation in the subworkflow. + tuple val(meta), path(vcf), path(vcf_index), path(refpanel), path(refpanel_index), path(genmap), path(exclsamples), path(exclmarkers), val(region) output: tuple val(meta), path("*.vcf.gz"), emit: vcf @@ -22,7 +24,8 @@ process BEAGLE5_BEAGLE { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}.bglout" def ref_command = refpanel ? "ref=$refpanel" : "" - def map_command = genmap ? "map=$genmap" : "" + def map_command = genmap ? "map=$genmap" : "" + def region_cmd = region ? "chrom=$region" : "" def excludesamples_command = exclsamples ? "excludesamples=$exclsamples" : "" def excludemarkers_command = exclmarkers ? "excludemarkers=$exclmarkers" : "" @@ -40,8 +43,9 @@ process BEAGLE5_BEAGLE { $args \\ ${ref_command} \\ ${map_command} \\ + ${region_cmd} \\ ${excludesamples_command} \\ - ${excludemarkers_command} \\ + ${excludemarkers_command} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/beagle5/beagle/meta.yml b/modules/nf-core/beagle5/beagle/meta.yml index 100d915bc59e..8f32c9a7c7ea 100644 --- a/modules/nf-core/beagle5/beagle/meta.yml +++ b/modules/nf-core/beagle5/beagle/meta.yml @@ -57,6 +57,10 @@ input: the analysis pattern: "*.*" ontologies: [] + - region: + type: string + description: Region to perform imputation + pattern: "(chr)?\\d*:\\d*-\\d*" output: vcf: - - meta: diff --git a/modules/nf-core/beagle5/beagle/tests/main.nf.test b/modules/nf-core/beagle5/beagle/tests/main.nf.test index a8aaee4d3402..6157c15b99d8 100644 --- a/modules/nf-core/beagle5/beagle/tests/main.nf.test +++ b/modules/nf-core/beagle5/beagle/tests/main.nf.test @@ -5,8 +5,6 @@ nextflow_process { script "../main.nf" process "BEAGLE5_BEAGLE" - config "./nextflow.config" - tag "modules" tag "modules_nfcore" tag "beagle5" @@ -15,16 +13,13 @@ nextflow_process { test("test-beagle5-beagle") { when { - params { - module_args = "" - } process { """ input[0] = [ [ id:'test', single_end:false ], // meta map 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), - [], [], [], [], [] + [], [], [], [], [], [] ] """ } @@ -46,9 +41,6 @@ nextflow_process { test("test-beagle5-beagle-ref") { when { - params { - module_args = "chrom=chr22" - } process { """ input[0] = [ @@ -57,7 +49,7 @@ nextflow_process { file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", 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" ] """ } @@ -78,9 +70,6 @@ nextflow_process { test("test-beagle5-beagle-ref-map") { when { - params { - module_args = "chrom=chr22" - } process { """ input[0] = [ @@ -90,7 +79,7 @@ nextflow_process { 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/genome/genetic_map/genome.GRCh38.chr22.plink.map"), - [], [] + [], [], "chr22" ] """ } @@ -112,16 +101,13 @@ nextflow_process { test("test-beagle5-beagle-ref-map - stub") { options '-stub' when { - params { - module_args = "" - } process { """ input[0] = [ [ id:'test', single_end:false ], // meta map 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), - [], [], [], [], [] + [], [], [], [], [], [] ] """ } diff --git a/modules/nf-core/beagle5/beagle/tests/nextflow.config b/modules/nf-core/beagle5/beagle/tests/nextflow.config deleted file mode 100644 index fe87f4a4cf57..000000000000 --- a/modules/nf-core/beagle5/beagle/tests/nextflow.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: "BEAGLE5_BEAGLE" { - ext.args = params.module_args - } -} diff --git a/subworkflows/nf-core/vcf_impute_beagle5/main.nf b/subworkflows/nf-core/vcf_impute_beagle5/main.nf new file mode 100644 index 000000000000..3ccb03229b61 --- /dev/null +++ b/subworkflows/nf-core/vcf_impute_beagle5/main.nf @@ -0,0 +1,116 @@ +include { BEAGLE5_BEAGLE } from '../../../modules/nf-core/beagle5/beagle' +include { BCFTOOLS_VIEW } from '../../../modules/nf-core/bcftools/view' +include { GLIMPSE2_LIGATE } from '../../../modules/nf-core/glimpse2/ligate' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_BEAGLE } from '../../../modules/nf-core/bcftools/index' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_LIGATE } from '../../../modules/nf-core/bcftools/index' + +workflow VCF_IMPUTE_BEAGLE5 { + + take: + ch_input // channel (mandatory): [ [id], vcf, tbi ] + ch_panel // channel (mandatory): [ [panel, chr], vcf, tbi ] + ch_chunks // channel (optional) : [ [panel, chr], regionout ] + ch_map // channel (optional) : [ [chr], map] + + main: + ch_versions = channel.empty() + + // Branch input files based on format + ch_input + .branch { _meta, vcf, _tbi -> + bcf: vcf.name.contains('.bcf') + vcf: vcf.name.contains('.vcf') + other: true + } + .set { ch_input_branched } + + ch_input_branched.other.map{ _meta, vcf, _tbi -> + error "ERROR: ${vcf.name} in ch_input channel must be in VCF or BCF format." + } + + // Convert BCF to VCF if necessary + BCFTOOLS_VIEW( + ch_input_branched.bcf, + [], [], [] + ) + ch_versions = ch_versions.mix(BCFTOOLS_VIEW.out.versions.first()) + + // Combine VCF files + ch_ready_vcf = ch_input_branched.vcf + .mix(BCFTOOLS_VIEW.out.vcf + .join( + BCFTOOLS_VIEW.out.csi + .mix(BCFTOOLS_VIEW.out.tbi) + ) + ) + + // Prepare input channels for BEAGLE5 by combining VCF, panel, and map files + ch_chunks_counts = ch_chunks + .groupTuple() + .map { metaPC, regionouts -> + [metaPC, regionouts.size()] + } + + ch_panel_map = ch_panel + .combine(ch_map, by: 0) + .combine(ch_chunks, by: 0) + .combine(ch_chunks_counts, by: 0) + + ch_panel_map.ifEmpty{ + error "ERROR: join operation resulted in an empty channel. Please provide a valid ch_panel and ch_map channel as input." + } + + ch_beagle_input = ch_ready_vcf + .combine(ch_panel_map) + .map { metaI, input_vcf, input_index, metaPC, panel_vcf, panel_index, map, regionout, regionsize -> [ + metaI + metaPC + ["regionout": regionout, "regionsize": regionsize], + input_vcf, input_index, + panel_vcf, panel_index, + map, [], [], regionout + ]} + + // Run BEAGLE5 imputation + BEAGLE5_BEAGLE(ch_beagle_input) + ch_versions = ch_versions.mix(BEAGLE5_BEAGLE.out.versions.first()) + + // Index the imputed VCF files + BCFTOOLS_INDEX_BEAGLE(BEAGLE5_BEAGLE.out.vcf) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_BEAGLE.out.versions.first()) + + // Ligate all phased files in one and index it + ligate_input = BEAGLE5_BEAGLE.out.vcf + .join( + BCFTOOLS_INDEX_BEAGLE.out.tbi + .mix(BCFTOOLS_INDEX_BEAGLE.out.csi) + ) + .map{ meta, vcf, index -> + def keysToKeep = meta.keySet() - ['regionout', 'regionsize'] + [ + groupKey(meta.subMap(keysToKeep), meta.regionsize), + vcf, index + ] + } + .groupTuple() + .map{ groupKeyObj, vcf, index -> + // Extract the actual meta from the groupKey + def meta = groupKeyObj.getGroupTarget() + [meta, vcf, index] + } + + GLIMPSE2_LIGATE( ligate_input ) + ch_versions = ch_versions.mix( GLIMPSE2_LIGATE.out.versions.first() ) + + BCFTOOLS_INDEX_LIGATE( GLIMPSE2_LIGATE.out.merged_variants ) + ch_versions = ch_versions.mix( BCFTOOLS_INDEX_LIGATE.out.versions.first() ) + + // Join imputed and index files + ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants + .join( + BCFTOOLS_INDEX_LIGATE.out.tbi + .mix(BCFTOOLS_INDEX_LIGATE.out.csi) + ) + + emit: + vcf_index = ch_vcf_index // channel: [ [id, chr, tools], vcf, index ] + versions = ch_versions // channel: [ versions.yml ] +} diff --git a/subworkflows/nf-core/vcf_impute_beagle5/meta.yml b/subworkflows/nf-core/vcf_impute_beagle5/meta.yml new file mode 100644 index 000000000000..a207e20bdfd1 --- /dev/null +++ b/subworkflows/nf-core/vcf_impute_beagle5/meta.yml @@ -0,0 +1,100 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: VCF_IMPUTE_BEAGLE5 +description: | + Subworkflow to impute VCF files using BEAGLE5 software. The subworkflow + takes VCF files, phased reference panel, genetic maps and chunks region to perform imputation + and outputs phased and imputed VCF files. + Meta map of all channels, except ch_input, will be used to perform joint operations. + "regionout" and "regionsize" keys will be added to the meta map to distinguish the different + file before ligation and therefore should not be used. +keywords: + - VCF + - imputation + - beagle5 + - phasing +components: + - beagle5/beagle + - bcftools/index + - bcftools/view + - glimpse2/ligate +input: + - ch_input: + description: Channel with input data + structure: + - meta: + type: map + description: | + Metadata map containing sample information + - vcf: + type: file + description: Input VCF files + pattern: "*.{vcf,bcf}{.gz}?" + - index: + type: file + description: Input index file + pattern: "*.{tbi,csi}" + - ch_panel: + description: Channel with phased reference panel data + structure: + - meta: + type: map + description: | + Metadata map that will be combined with the input data map + - vcf: + type: file + description: Reference panel VCF files by chromosomes + pattern: "*.{vcf,bcf,vcf.gz}" + - index: + type: file + description: Reference panel VCF index files + pattern: "*.{tbi,csi}" + - ch_chunks: + description: Channel containing the region to impute + structure: + - meta: + type: map + description: | + Metadata map containing chromosome information + - regionout: + type: string + description: Region to perform the phasing on + pattern: "[chr]+[0-9]+:[0-9]+-[0-9]+" + - ch_map: + description: Channel with genetic map data + structure: + - meta: + type: map + description: | + Metadata map containing chromosome information + - map: + type: file + description: Plink format genetic map files + pattern: "*.map" +output: + - vcf_index: + description: Channel with imputed and phased VCF files + structure: + - meta: + type: map + description: | + Metadata map of the target input file combined with the reference panel map. + - vcf: + type: file + description: VCF imputed and phased file by sample + pattern: "*.{vcf,bcf,vcf.gz}" + - index: + type: file + description: VCF index file + pattern: "*.{tbi,csi}" + - versions: + description: Channel containing software versions file + structure: + - versions.yml: + type: file + description: File containing versions of the software used +authors: + - "@LouisLeNezet" + - "@gichas" +maintainers: + - "@LouisLeNezet" + - "@gichas" diff --git a/subworkflows/nf-core/vcf_impute_beagle5/tests/main.nf.test b/subworkflows/nf-core/vcf_impute_beagle5/tests/main.nf.test new file mode 100644 index 000000000000..448d23769d66 --- /dev/null +++ b/subworkflows/nf-core/vcf_impute_beagle5/tests/main.nf.test @@ -0,0 +1,237 @@ +nextflow_workflow { + + name "Test Subworkflow VCF_IMPUTE_BEAGLE5" + script "../main.nf" + workflow "VCF_IMPUTE_BEAGLE5" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/vcf_impute_beagle5" + + config "./nextflow.config" + + tag "beagle5" + tag "beagle5/beagle" + tag "bcftools" + tag "bcftools/index" + tag "bcftools/view" + tag "glimpse2" + tag "glimpse2/ligate" + + + test("Impute with beagle5 one vcf - panel - whole chromosome - no map - one chromosomes") { + when { + workflow { + """ + input[0] = Channel.of([ + [id: "NA12878"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExist:true) + ]) + input[1] = Channel.of([ + [panel: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz.csi", checkIfExist:true) + ]) + input[2] = Channel.of([[panel: "1000GP", chr: "chr22"], "chr22"]) // chunks + input[3] = Channel.of([[panel: "1000GP", chr: "chr22"], []]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.vcf_index.collect{[ + it[0], + path(it[1]).getFileName().toString(), + path(it[2]).getFileName().toString(), + path(it[1]).vcf.summary, + path(it[1]).vcf.header.getGenotypeSamples().sort(), + path(it[1]).vcf.variantsMD5 + ]}, + workflow.out.versions, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + + test("Impute with beagle5 one bcf gz - panel - map - chunks - two chrosomes") { + setup { + run ("BCFTOOLS_VIEW", alias: "BCFTOOLS_VIEW_BCF" ) { + script "../../../../modules/nf-core/bcftools/view" + process { + """ + input[0] = channel.of([ + [id: "NA12878"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExist:true) + ]) + input[1] = [] + input[2] = [] + input[3] = [] + """ + } + } + } + when { + params { + bcftools_view_args = "--write-index=csi --output-type b" + } + workflow { + """ + input[0] = BCFTOOLS_VIEW_BCF.out.vcf.join(BCFTOOLS_VIEW_BCF.out.csi) + input[1] = channel.of([ + [panel: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz.csi", checkIfExist:true) + ],[ + [panel: "1000GP", chr: "chr21"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz.csi", checkIfExist:true) + ]) + input[2] = channel.of( + [[chr: "chr22", panel: "1000GP"], "chr22:16570065-16592216"], + [[chr: "chr22", panel: "1000GP"], "chr22:16592229-16609999"], + [[chr: "chr21", panel: "1000GP"], "chr21:16570065-16592216"], + [[chr: "chr21", panel: "1000GP"], "chr21:16592229-16609999"] + ) + input[3] = channel.of([ + [panel: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.plink.map", checkIfExist:true) + ],[ + [panel: "1000GP", chr: "chr21"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr21.plink.map", checkIfExist:true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.vcf_index.collect{[ + it[0], + path(it[1]).getFileName().toString(), + path(it[2]).getFileName().toString(), + path(it[1]).vcf.summary, + path(it[1]).vcf.header.getGenotypeSamples().sort(), + path(it[1]).vcf.variantsMD5 + ]}, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + + test("homo_sapiens - empty channels - stub") { + options "-stub" + when { + workflow { + """ + input[0] = channel.of([ + [id: "NA12878"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExist:true) + ]) + input[1] = channel.of( + [[panel: "1000GP", chr: "chr22"], [], []], + [[panel: "1000GP", chr: "chr21"], [], []] + ) + input[2] = channel.of( + [[chr: "chr22", panel: "1000GP"], "chr22:16570065-16592216"], + [[chr: "chr22", panel: "1000GP"], "chr22:16592229-16609999"], + [[chr: "chr21", panel: "1000GP"], "chr21:16570065-16592216"], + [[chr: "chr21", panel: "1000GP"], "chr21:16592229-16609999"] + ) + input[3] = channel.of( + [[panel: "1000GP", chr: "chr22"], []], + [[panel: "1000GP", chr: "chr21"], []] + ) + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + + test("homo_sapiens - error wrong input format - stub") { + options "-stub" + when { + workflow { + """ + input[0] = channel.of([ + [id: "NA12878"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.minimac.map", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExist:true) + ]) + input[1] = channel.of( + [[panel: "1000GP", chr: "chr22"], [], []], + [[panel: "1000GP", chr: "chr21"], [], []] + ) + input[2] = channel.of( + [[chr: "chr22", panel: "1000GP"], "chr22:16570065-16592216"], + [[chr: "chr22", panel: "1000GP"], "chr22:16592229-16609999"], + [[chr: "chr21", panel: "1000GP"], "chr21:16570065-16592216"], + [[chr: "chr21", panel: "1000GP"], "chr21:16592229-16609999"] + ) + input[3] = channel.of( + [[panel: "1000GP", chr: "chr22"], []], + [[panel: "1000GP", chr: "chr21"], []] + ) + """ + } + } + then { + assertAll( + { assert workflow.failed }, + { assert workflow.errorMessage.contains("ERROR: genome.GRCh38.chr22.minimac.map in ch_input channel must be in VCF or BCF format.") } + ) + } + } + + test("homo_sapiens - error empty joint - stub") { + options "-stub" + when { + workflow { + """ + input[0] = channel.of([ + [id: "NA12878"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExist:true) + ]) + input[1] = channel.of( + [[panel: "1000GP_1", chr: "chr22"], [], []], // Wrong panel + [[panel: "1000GP", chr: "chr21"], [], []] + ) + input[2] = channel.of( + [[chr: "chr22", panel: "1000GP"], "chr22:16570065-16592216"], + [[chr: "chr22", panel: "1000GP"], "chr22:16592229-16609999"], + [[chr: "chr21", panel: "1000GP"], "chr21:16570065-16592216"], + [[chr: "chr21", panel: "1000GP"], "chr21:16592229-16609999"] + ) + input[3] = channel.of( + [[panel: "1000GP", chr: "chr22"], []], + [[panel: "1000GP_1", chr: "chr21"], []] // Wrong panel + ) + """ + } + } + then { + assertAll( + { assert workflow.failed }, + { assert workflow.errorMessage.contains("ERROR: join operation resulted in an empty channel. Please provide a valid ch_panel and ch_map channel as input.") } + ) + } + } +} diff --git a/subworkflows/nf-core/vcf_impute_beagle5/tests/main.nf.test.snap b/subworkflows/nf-core/vcf_impute_beagle5/tests/main.nf.test.snap new file mode 100644 index 000000000000..36c113694362 --- /dev/null +++ b/subworkflows/nf-core/vcf_impute_beagle5/tests/main.nf.test.snap @@ -0,0 +1,206 @@ +{ + "Impute with beagle5 one vcf - panel - whole chromosome - no map - one chromosomes": { + "content": [ + [ + [ + { + "id": "NA12878", + "panel": "1000GP", + "chr": "chr22" + }, + "NA12878_chr22.ligate.vcf.gz", + "NA12878_chr22.ligate.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=903, phased=true, phasedAutodetect=true]", + [ + "NA12878" + ], + "9cab6e975108d5f6dbb7773b794711c2" + ] + ], + [ + "versions.yml:md5,055ba50f00b32df929e0e147ba6d4408", + "versions.yml:md5,3ba3affc995d9a03ef59f8cf9e7fac38", + "versions.yml:md5,e4c10555396b9a57ef3aafc9a4707963", + "versions.yml:md5,ff3101d4f934dc550b466d79e092707c" + ], + [ + { + "VCF_IMPUTE_BEAGLE5:BCFTOOLS_INDEX_BEAGLE": { + "bcftools": 1.22 + } + }, + { + "VCF_IMPUTE_BEAGLE5:BEAGLE5_BEAGLE": { + "beagle": "5.5rev27Feb25.75f" + } + }, + { + "VCF_IMPUTE_BEAGLE5:BCFTOOLS_INDEX_LIGATE": { + "bcftools": 1.22 + } + }, + { + "VCF_IMPUTE_BEAGLE5:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-11T10:40:58.515114119" + }, + "homo_sapiens - empty channels - stub": { + "content": [ + { + "0": [ + [ + { + "id": "NA12878", + "chr": "chr21", + "panel": "1000GP" + }, + "NA12878_chr21.ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "NA12878_chr21.ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "NA12878", + "chr": "chr22", + "panel": "1000GP" + }, + "NA12878_chr22.ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "NA12878_chr22.ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,055ba50f00b32df929e0e147ba6d4408", + "versions.yml:md5,3ba3affc995d9a03ef59f8cf9e7fac38", + "versions.yml:md5,e4c10555396b9a57ef3aafc9a4707963", + "versions.yml:md5,ff3101d4f934dc550b466d79e092707c" + ], + "vcf_index": [ + [ + { + "id": "NA12878", + "chr": "chr21", + "panel": "1000GP" + }, + "NA12878_chr21.ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "NA12878_chr21.ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "NA12878", + "chr": "chr22", + "panel": "1000GP" + }, + "NA12878_chr22.ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "NA12878_chr22.ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,055ba50f00b32df929e0e147ba6d4408", + "versions.yml:md5,3ba3affc995d9a03ef59f8cf9e7fac38", + "versions.yml:md5,e4c10555396b9a57ef3aafc9a4707963", + "versions.yml:md5,ff3101d4f934dc550b466d79e092707c" + ] + }, + [ + { + "VCF_IMPUTE_BEAGLE5:BCFTOOLS_INDEX_BEAGLE": { + "bcftools": 1.22 + } + }, + { + "VCF_IMPUTE_BEAGLE5:BEAGLE5_BEAGLE": { + "beagle": "5.5rev27Feb25.75f" + } + }, + { + "VCF_IMPUTE_BEAGLE5:BCFTOOLS_INDEX_LIGATE": { + "bcftools": 1.22 + } + }, + { + "VCF_IMPUTE_BEAGLE5:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-11T10:37:59.303608442" + }, + "Impute with beagle5 one bcf gz - panel - map - chunks - two chrosomes": { + "content": [ + [ + [ + { + "id": "NA12878", + "chr": "chr21", + "panel": "1000GP" + }, + "NA12878_chr21.ligate.vcf.gz", + "NA12878_chr21.ligate.vcf.gz.csi", + "VcfFile [chromosomes=[chr21], sampleCount=1, variantCount=836, phased=true, phasedAutodetect=true]", + [ + "NA12878" + ], + "70c852b39eb228a54fabc564d7e536e4" + ], + [ + { + "id": "NA12878", + "chr": "chr22", + "panel": "1000GP" + }, + "NA12878_chr22.ligate.vcf.gz", + "NA12878_chr22.ligate.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=903, phased=true, phasedAutodetect=true]", + [ + "NA12878" + ], + "9cab6e975108d5f6dbb7773b794711c2" + ] + ], + [ + { + "VCF_IMPUTE_BEAGLE5:BCFTOOLS_INDEX_BEAGLE": { + "bcftools": 1.22 + } + }, + { + "VCF_IMPUTE_BEAGLE5:BEAGLE5_BEAGLE": { + "beagle": "5.5rev27Feb25.75f" + } + }, + { + "VCF_IMPUTE_BEAGLE5:BCFTOOLS_INDEX_LIGATE": { + "bcftools": 1.22 + } + }, + { + "VCF_IMPUTE_BEAGLE5:BCFTOOLS_VIEW": { + "bcftools": 1.22 + } + }, + { + "VCF_IMPUTE_BEAGLE5:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-11T10:41:17.021023357" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/vcf_impute_beagle5/tests/nextflow.config b/subworkflows/nf-core/vcf_impute_beagle5/tests/nextflow.config new file mode 100644 index 000000000000..9be75a1c7cb9 --- /dev/null +++ b/subworkflows/nf-core/vcf_impute_beagle5/tests/nextflow.config @@ -0,0 +1,25 @@ +process { + withName: BCFTOOLS_VIEW { + ext.args = { "--write-index=tbi --output-type z" } + } + + withName: BEAGLE5_BEAGLE { + ext.prefix = { "${meta.id}_${meta.regionout}" } + } + + withName: GLIMPSE2_LIGATE { + ext.prefix = { "${meta.id}_${meta.chr}.ligate" } + } + + withName: BCFTOOLS_INDEX_BEAGLE { + ext.args = '--tbi' + } + + withName: BCFTOOLS_INDEX_LIGATE { + ext.args = '--csi' + } + + withName: BCFTOOLS_VIEW_BCF { + ext.args = { params.bcftools_view_args ?: "" } + } +} From 2c74f429e26577ad31a42295d6271ebfec6f1261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Thu, 11 Dec 2025 18:35:13 +0100 Subject: [PATCH 67/83] Add minimac4 imputation subworkfllow (#9451) * Add vcf_impute_minimac4 * Update linting * Update test * Fix linting * Update minimac4 sbwf * Remove tag * Remove tag * Fix linting * Add comment * Update snapshot * Fix nf-test --- modules/nf-core/minimac4/impute/main.nf | 14 +- modules/nf-core/minimac4/impute/meta.yml | 4 + .../minimac4/impute/tests/main.nf.test | 6 +- .../nf-core/vcf_impute_minimac4/main.nf | 97 +++++++ .../nf-core/vcf_impute_minimac4/meta.yml | 116 ++++++++ .../vcf_impute_minimac4/tests/main.nf.test | 261 ++++++++++++++++++ .../tests/main.nf.test.snap | 212 ++++++++++++++ .../vcf_impute_minimac4/tests/nextflow.config | 21 ++ 8 files changed, 722 insertions(+), 9 deletions(-) create mode 100644 subworkflows/nf-core/vcf_impute_minimac4/main.nf create mode 100644 subworkflows/nf-core/vcf_impute_minimac4/meta.yml create mode 100644 subworkflows/nf-core/vcf_impute_minimac4/tests/main.nf.test create mode 100644 subworkflows/nf-core/vcf_impute_minimac4/tests/main.nf.test.snap create mode 100644 subworkflows/nf-core/vcf_impute_minimac4/tests/nextflow.config diff --git a/modules/nf-core/minimac4/impute/main.nf b/modules/nf-core/minimac4/impute/main.nf index d4a3e52201dd..c26454cc4dab 100644 --- a/modules/nf-core/minimac4/impute/main.nf +++ b/modules/nf-core/minimac4/impute/main.nf @@ -8,7 +8,7 @@ process MINIMAC4_IMPUTE { 'biocontainers/minimac4:4.1.6--hcb620b3_1' }" input: - tuple val(meta), path(target_vcf), path(target_index), path(ref_msav), path(sites_vcf), path(sites_index), path(map) + tuple val(meta), path(target_vcf), path(target_index), path(ref_msav), path(sites_vcf), path(sites_index), path(map), val(region) output: tuple val(meta), path("*.{bcf,sav,vcf.gz,vcf,ubcf,usav}"), emit: vcf @@ -18,17 +18,18 @@ process MINIMAC4_IMPUTE { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-format bcf") || args.contains("-O bcf") ? "bcf" : + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def extension = args.contains("--output-format bcf") || args.contains("-O bcf") ? "bcf" : args.contains("--output-format sav") || args.contains("-O sav") ? "sav" : args.contains("--output-format vcf.gz") || args.contains("-O vcf.gz") ? "vcf.gz" : args.contains("--output-format vcf") || args.contains("-O vcf") ? "vcf" : args.contains("--output-format ubcf") || args.contains("-O ubcf") ? "ubcf" : args.contains("--output-format usav") || args.contains("-O usav") ? "usav" : "vcf.gz" - def sites_cmd = sites_vcf ? "--sites $sites_vcf" : "" - def map_cmd = map ? "--map $map" : "" + def sites_cmd = sites_vcf ? "--sites $sites_vcf" : "" + def map_cmd = map ? "--map $map" : "" + def region_cmd = region ? "--region $region" : "" """ minimac4 \\ $ref_msav \\ @@ -36,6 +37,7 @@ process MINIMAC4_IMPUTE { $args \\ $sites_cmd \\ $map_cmd \\ + $region_cmd \\ --threads $task.cpus \\ -o ${prefix}.${extension} diff --git a/modules/nf-core/minimac4/impute/meta.yml b/modules/nf-core/minimac4/impute/meta.yml index 6c7cbf7b791e..5c1931b07c71 100644 --- a/modules/nf-core/minimac4/impute/meta.yml +++ b/modules/nf-core/minimac4/impute/meta.yml @@ -58,6 +58,10 @@ input: pattern: "*.map" ontologies: - edam: "http://edamontology.org/data_1278" + - region: + type: string + description: Region to perform imputation + pattern: "(chr)?\\d*:\\d*-\\d*" output: vcf: diff --git a/modules/nf-core/minimac4/impute/tests/main.nf.test b/modules/nf-core/minimac4/impute/tests/main.nf.test index d2d075b6fb15..9657df7a8151 100644 --- a/modules/nf-core/minimac4/impute/tests/main.nf.test +++ b/modules/nf-core/minimac4/impute/tests/main.nf.test @@ -45,7 +45,7 @@ nextflow_process { .combine(MINIMAC4_COMPRESSREF.out.msav) .map{ meta, target_vcf, target_index, sites_vcf, sites_index, map, metaRef, ref -> [ - meta, target_vcf, target_index, ref, sites_vcf, sites_index, map + meta, target_vcf, target_index, ref, sites_vcf, sites_index, map, "chr22" ] } """ @@ -86,7 +86,7 @@ nextflow_process { .combine(MINIMAC4_COMPRESSREF.out.msav) .map{ meta, target_vcf, target_index, metaRef, ref -> [ - meta, target_vcf, target_index, ref, [], [], [] + meta, target_vcf, target_index, ref, [], [], [], [] ] } """ @@ -126,7 +126,7 @@ nextflow_process { [id: "NA12878", chr: "chr22"], 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), - [], [], [], [] + [], [], [], [], [] ]) """ } diff --git a/subworkflows/nf-core/vcf_impute_minimac4/main.nf b/subworkflows/nf-core/vcf_impute_minimac4/main.nf new file mode 100644 index 000000000000..0fcc3dd98ea1 --- /dev/null +++ b/subworkflows/nf-core/vcf_impute_minimac4/main.nf @@ -0,0 +1,97 @@ +include { MINIMAC4_COMPRESSREF } from '../../../modules/nf-core/minimac4/compressref' +include { MINIMAC4_IMPUTE } from '../../../modules/nf-core/minimac4/impute' +include { GLIMPSE2_LIGATE } from '../../../modules/nf-core/glimpse2/ligate' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_PHASE } from '../../../modules/nf-core/bcftools/index' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_LIGATE } from '../../../modules/nf-core/bcftools/index' + +workflow VCF_IMPUTE_MINIMAC4 { + take: + ch_input // channel (mandatory): [ [id, chr], vcf, tbi ] + ch_panel // channel (mandatory): [ [panel, chr], vcf, tbi ] + ch_posfile // channel (optional) : [ [panel, chr], sites_vcf, sites_index ] + ch_chunks // channel (optional) : [ [panel, chr], regionout ] + ch_map // channel (optional) : [ [panel, chr], map] + + main: + + ch_versions = channel.empty() + + ch_panel_branched = ch_panel.branch { _meta, file, _index -> + def name = file.toString() + vcf: name.matches(/.*\.(vcf|bcf)(\.gz)?$/) + msav: name.endsWith('.msav') + other: true + } + + ch_panel_branched.other.map { + error("ERROR: ch_panel files must be either VCF/BCF or MSAV.") + } + + // Compress reference panel to MSAV format + MINIMAC4_COMPRESSREF(ch_panel_branched.vcf) + ch_versions = ch_versions.mix(MINIMAC4_COMPRESSREF.out.versions.first()) + + ch_panel_msav = MINIMAC4_COMPRESSREF.out.msav.mix( + ch_panel_branched.msav.map { meta, file, _index -> [meta, file] } + ) + + // Channel with all reference and chunks informations + // [ meta, reference panel msav, sites to impute vcf, sites index, region to impute, genetic map ] + ch_panel_impute = ch_panel_msav + .combine(ch_posfile, by: 0) + .combine(ch_chunks, by: 0) + .combine(ch_map, by: 0) + + ch_panel_impute.ifEmpty { + error("ERROR: join operation resulted in an empty channel. Please provide a valid ch_posfile, ch_chunks and ch_map channel as input.") + } + + // Prepare input channels for MINIMAC4 + ch_minimac4_input = ch_input + .combine(ch_panel_impute) + .map { metaI, target_vcf, target_tbi, metaPC, ref_msav, sites_vcf, sites_index, regionout, map -> + [ + metaPC + metaI + ["regionout": regionout], + target_vcf, + target_tbi, + ref_msav, + sites_vcf, + sites_index, + map, + regionout, + ] + } + // Perform imputation + MINIMAC4_IMPUTE(ch_minimac4_input) + ch_versions = ch_versions.mix(MINIMAC4_IMPUTE.out.versions.first()) + + // Index the output VCF file + BCFTOOLS_INDEX_PHASE(MINIMAC4_IMPUTE.out.vcf) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_PHASE.out.versions.first()) + + // Ligate all phased files in one and index it + ligate_input = MINIMAC4_IMPUTE.out.vcf + .join( + BCFTOOLS_INDEX_PHASE.out.tbi.mix(BCFTOOLS_INDEX_PHASE.out.csi) + ) + .map { meta, vcf, index -> + def keysToKeep = meta.keySet() - ['regionout'] + [meta.subMap(keysToKeep), vcf, index] + } + .groupTuple() + + GLIMPSE2_LIGATE(ligate_input) + ch_versions = ch_versions.mix(GLIMPSE2_LIGATE.out.versions.first()) + + BCFTOOLS_INDEX_LIGATE(GLIMPSE2_LIGATE.out.merged_variants) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_LIGATE.out.versions.first()) + + // Join imputed and index files + ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants.join( + BCFTOOLS_INDEX_LIGATE.out.tbi.mix(BCFTOOLS_INDEX_LIGATE.out.csi) + ) + + emit: + vcf_index = ch_vcf_index // channel: [ [id, panel, chr], vcf, index ] + versions = ch_versions // channel: [ versions.yml ] +} diff --git a/subworkflows/nf-core/vcf_impute_minimac4/meta.yml b/subworkflows/nf-core/vcf_impute_minimac4/meta.yml new file mode 100644 index 000000000000..1b1273c73b0f --- /dev/null +++ b/subworkflows/nf-core/vcf_impute_minimac4/meta.yml @@ -0,0 +1,116 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "VCF_IMPUTE_MINIMAC4" +description: | + Subworkflow to impute VCF files using MINIMAC4 software. The subworkflow + takes VCF files, phased reference panel, and genetic maps to perform imputation + and outputs phased and imputed VCF files. + Meta map of all channels, except ch_input, will be used to perform joint operations. + "regionout" key will be added to the meta map to distinguish the different file + before ligation and therefore should not be used. +keywords: + - VCF + - imputation + - minimac4 + - phasing + - MSAV +components: + - minimac4/compressref + - minimac4/impute + - bcftools/index + - glimpse2/ligate +input: + - ch_input: + description: Channel with input data + structure: + - meta: + type: map + description: | + Metadata map containing sample information + - vcf: + type: file + description: Input VCF files + pattern: "*.{vcf,bcf,vcf.gz}" + - index: + type: file + description: Input index file + pattern: "*.{tbi,csi}" + - ch_panel: + description: Channel with phased reference panel data + structure: + - meta: + type: map + description: | + Metadata map that will be combined with the input data map + - vcf: + type: file + description: Reference panel VCF files by chromosomes + pattern: "*.{vcf,bcf,vcf.gz}" + - index: + type: file + description: Reference panel VCF index files + pattern: "*.{tbi,csi}" + - ch_posfile: + description: Channel with variants position to impute + structure: + - meta: + type: map + description: | + Metadata map containing chromosome information + - sites_vcf: + type: file + descrition: | + VCF/BCF file containing position to impute + - sites_index: + type: file + description: | + CSI|TBI index file of the sites to impute + - ch_chunks: + description: Channel containing the region to impute + structure: + - meta: + type: map + description: | + Metadata map containing chromosome information + - regionout: + type: string + description: Region to perform the phasing on + pattern: "[chr]+[0-9]+:[0-9]+-[0-9]+" + - ch_map: + description: Channel with genetic map data + structure: + - meta: + type: map + description: | + Metadata map containing chromosome information + - map: + type: file + description: Minimac format genetic map files + pattern: "*.map" +output: + - vcf_index: + description: Channel with imputed and phased VCF files + structure: + - meta: + type: map + description: | + Metadata map of the target input file combined with the reference panel map. + - vcf: + type: file + description: VCF imputed and phased file by sample + pattern: "*.{vcf,bcf,vcf.gz}" + - index: + type: file + description: VCF index file + pattern: "*.{tbi,csi}" + - versions: + description: Channel containing software versions file + structure: + - versions.yml: + type: file + description: File containing versions of the software used +authors: + - "@LouisLeNezet" + - "@gichas" +maintainers: + - "@LouisLeNezet" + - "@gichas" diff --git a/subworkflows/nf-core/vcf_impute_minimac4/tests/main.nf.test b/subworkflows/nf-core/vcf_impute_minimac4/tests/main.nf.test new file mode 100644 index 000000000000..5ef6df8ec107 --- /dev/null +++ b/subworkflows/nf-core/vcf_impute_minimac4/tests/main.nf.test @@ -0,0 +1,261 @@ +nextflow_workflow { + + name "Test Subworkflow VCF_IMPUTE_MINIMAC4" + script "../main.nf" + + config "./nextflow.config" + + workflow "VCF_IMPUTE_MINIMAC4" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/vcf_impute_minimac4" + + tag "minimac4" + tag "minimac4/compressref" + tag "minimac4/impute" + tag "bcftools" + tag "bcftools/index" + tag "glimpse2" + tag "glimpse2/ligate" + + test("Impute with minimac4 one vcf no map, no posfile, no chunks, panel as vcf") { + when { + workflow { + """ + input[0] = Channel.of([ + [id: "NA12878"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExist:true) + ]) + input[1] = Channel.of([ + [id: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz.csi", checkIfExist:true) + ]) + input[2] = Channel.of([[id: "1000GP", chr: "chr22"], [], []]) + input[3] = Channel.of([[id: "1000GP", chr: "chr22"], "chr22"]) + input[4] = Channel.of([[id: "1000GP", chr: "chr22"], []]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.vcf_index.collect{[ + it[0], + path(it[1]).getFileName().toString(), + path(it[2]).getFileName().toString(), + path(it[1]).vcf.summary, + path(it[1]).vcf.header.getGenotypeSamples().sort(), + path(it[1]).vcf.variantsMD5 + ]}, + workflow.out.versions, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + + test("Impute with minimac4 one vcf with map, posfile, chunks, panel as vcf") { + when { + workflow { + """ + input[0] = channel.of([ + [id: "NA12878"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExist:true) + ]) + input[1] = channel.of( + [ + [id: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz.csi", checkIfExist:true) + ],[ + [id: "1000GP", chr: "chr21"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz.csi", checkIfExist:true) + ]) + input[2] = channel.of( + [ + [id: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.sites.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.sites.vcf.gz.csi", checkIfExist:true) + ],[ + [id: "1000GP", chr: "chr21"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.sites.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.sites.vcf.gz.csi", checkIfExist:true) + ]) + input[3] = channel.of( + [[chr: "chr22", id: "1000GP"], "chr22:16570065-16592216"], + [[chr: "chr22", id: "1000GP"], "chr22:16592229-16609999"], + [[chr: "chr21", id: "1000GP"], "chr21:16570065-16592216"], + [[chr: "chr21", id: "1000GP"], "chr21:16592229-16609999"] + ) + input[4] = channel.of([ + [id: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.minimac.map", checkIfExist:true) + ],[ + [id: "1000GP", chr: "chr21"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr21.minimac.map", checkIfExist:true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.vcf_index.collect{[ + it[0], + path(it[1]).getFileName().toString(), + path(it[2]).getFileName().toString(), + path(it[1]).vcf.summary, + path(it[1]).vcf.header.getGenotypeSamples().sort(), + path(it[1]).vcf.variantsMD5 + ]}, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + + test("homo_sapiens - empty channels - stub") { + options "-stub" + when { + workflow { + """ + input[0] = channel.of([ + [id: "NA12878"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExist:true) + ]) + input[1] = channel.of( + [ + [id: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz.csi", checkIfExist:true) + ],[ + [id: "1000GP", chr: "chr21"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz.csi", checkIfExist:true) + ]) + input[2] = channel.of( + [[id: "1000GP", chr: "chr22"],[],[]], + [[id: "1000GP", chr: "chr21"],[],[]] + ) + input[3] = channel.of( + [[chr: "chr22", id: "1000GP"], "chr22:16570065-16592216"], + [[chr: "chr22", id: "1000GP"], "chr22:16592229-16609999"], + [[chr: "chr21", id: "1000GP"], "chr21:16570065-16592216"], + [[chr: "chr21", id: "1000GP"], "chr21:16592229-16609999"] + ) + input[4] = channel.of( + [[id: "1000GP", chr: "chr22"], []], + [[id: "1000GP", chr: "chr21"], []] + ) + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out, + workflow.out.versions.collect{ path(it).yaml } + ).match() } + ) + } + } + + test("homo_sapiens - error wrong panel format - stub") { + options "-stub" + when { + workflow { + """ + input[0] = channel.of([ + [id: "NA12878"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExist:true) + ]) + input[1] = channel.of( + [ + [id: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.minimac.map", checkIfExist:true), + [] + ], + [[id: "1000GP", chr: "chr21"],[],[]] + ) + input[2] = channel.of( + [[id: "1000GP", chr: "chr22"],[],[]], + [[id: "1000GP", chr: "chr21"],[],[]] + ) + input[3] = channel.of( + [[chr: "chr22", id: "1000GP"], "chr22:16570065-16592216"], + [[chr: "chr22", id: "1000GP"], "chr22:16592229-16609999"], + [[chr: "chr21", id: "1000GP"], "chr21:16570065-16592216"], + [[chr: "chr21", id: "1000GP"], "chr21:16592229-16609999"] + ) + input[4] = channel.of( + [[id: "1000GP", chr: "chr22"], []], + [[id: "1000GP", chr: "chr21"], []] + ) + """ + } + } + then { + assertAll( + { assert workflow.failed }, + { assert filterNextflowOutput(workflow.stdout).contains("ERROR: ch_panel files must be either VCF/BCF or MSAV.") } + ) + } + } + + test("homo_sapiens - error empty joint - stub") { + options "-stub" + when { + workflow { + """ + input[0] = channel.of([ + [id: "NA12878"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi", checkIfExist:true) + ]) + input[1] = channel.of( + [ + [id: "1000GP", chr: "chr22"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz.csi", checkIfExist:true) + ],[ + [id: "1000GP", chr: "chr21"], + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz", checkIfExist:true), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/popgen/1000GP.chr21.vcf.gz.csi", checkIfExist:true) + ]) + input[2] = channel.of( + [[id: "1000GP", chr: "chr22"],[],[]], + [[id: "1000GP_2", chr: "chr21"],[],[]] // Wrong panel + ) + input[3] = channel.of( + [[chr: "chr22", id: "1000GP"], "chr22:16570065-16592216"], + [[chr: "chr22", id: "1000GP"], "chr22:16592229-16609999"], + [[chr: "chr21", id: "1000GP"], "chr21:16570065-16592216"], + [[chr: "chr21", id: "1000GP"], "chr21:16592229-16609999"] + ) + input[4] = channel.of( + [[id: "1000GP_1", chr: "chr22"], []], // Wrong panel + [[id: "1000GP", chr: "chr21"], []] + ) + """ + } + } + then { + assertAll( + { assert workflow.failed }, + { assert filterNextflowOutput(workflow.stdout).contains("ERROR: join operation resulted in an empty channel. Please provide a valid ch_posfile, ch_chunks and ch_map channel as input.") } + ) + } + } +} diff --git a/subworkflows/nf-core/vcf_impute_minimac4/tests/main.nf.test.snap b/subworkflows/nf-core/vcf_impute_minimac4/tests/main.nf.test.snap new file mode 100644 index 000000000000..acd4516a26c1 --- /dev/null +++ b/subworkflows/nf-core/vcf_impute_minimac4/tests/main.nf.test.snap @@ -0,0 +1,212 @@ +{ + "homo_sapiens - empty channels - stub": { + "content": [ + { + "0": [ + [ + { + "id": "NA12878", + "chr": "chr21" + }, + "NA12878_chr21.ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "NA12878_chr21.ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "NA12878", + "chr": "chr22" + }, + "NA12878_chr22.ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "NA12878_chr22.ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,373fe12da367d3891473f487a9536d04", + "versions.yml:md5,8a6808c992b87d05442e61783f97b72e", + "versions.yml:md5,a4842af8fedc3522b989d4ee28f08d80", + "versions.yml:md5,c4f18dd6f40ed9d3800cf2343ea37718", + "versions.yml:md5,d338622357eb167be72947a2d0cb1f43" + ], + "vcf_index": [ + [ + { + "id": "NA12878", + "chr": "chr21" + }, + "NA12878_chr21.ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "NA12878_chr21.ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "NA12878", + "chr": "chr22" + }, + "NA12878_chr22.ligate.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "NA12878_chr22.ligate.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,373fe12da367d3891473f487a9536d04", + "versions.yml:md5,8a6808c992b87d05442e61783f97b72e", + "versions.yml:md5,a4842af8fedc3522b989d4ee28f08d80", + "versions.yml:md5,c4f18dd6f40ed9d3800cf2343ea37718", + "versions.yml:md5,d338622357eb167be72947a2d0cb1f43" + ] + }, + [ + { + "VCF_IMPUTE_MINIMAC4:MINIMAC4_COMPRESSREF": { + "minimac4": "4.1.6" + } + }, + { + "VCF_IMPUTE_MINIMAC4:BCFTOOLS_INDEX_LIGATE": { + "bcftools": 1.22 + } + }, + { + "VCF_IMPUTE_MINIMAC4:MINIMAC4_IMPUTE": { + "minimac4": "4.1.6" + } + }, + { + "VCF_IMPUTE_MINIMAC4:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + }, + { + "VCF_IMPUTE_MINIMAC4:BCFTOOLS_INDEX_PHASE": { + "bcftools": 1.22 + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-11T11:59:53.921713709" + }, + "Impute with minimac4 one vcf no map, no posfile, no chunks, panel as vcf": { + "content": [ + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + "NA12878_chr22.ligate.vcf.gz", + "NA12878_chr22.ligate.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=903, phased=true, phasedAutodetect=true]", + [ + "NA12878" + ], + "a0615a8a5ce53f496ac691c5fc82a44" + ] + ], + [ + "versions.yml:md5,373fe12da367d3891473f487a9536d04", + "versions.yml:md5,8a6808c992b87d05442e61783f97b72e", + "versions.yml:md5,a4842af8fedc3522b989d4ee28f08d80", + "versions.yml:md5,c4f18dd6f40ed9d3800cf2343ea37718", + "versions.yml:md5,d338622357eb167be72947a2d0cb1f43" + ], + [ + { + "VCF_IMPUTE_MINIMAC4:MINIMAC4_COMPRESSREF": { + "minimac4": "4.1.6" + } + }, + { + "VCF_IMPUTE_MINIMAC4:BCFTOOLS_INDEX_LIGATE": { + "bcftools": 1.22 + } + }, + { + "VCF_IMPUTE_MINIMAC4:MINIMAC4_IMPUTE": { + "minimac4": "4.1.6" + } + }, + { + "VCF_IMPUTE_MINIMAC4:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + }, + { + "VCF_IMPUTE_MINIMAC4:BCFTOOLS_INDEX_PHASE": { + "bcftools": 1.22 + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-11T14:09:22.856397388" + }, + "Impute with minimac4 one vcf with map, posfile, chunks, panel as vcf": { + "content": [ + [ + [ + { + "id": "NA12878", + "chr": "chr21" + }, + "NA12878_chr21.ligate.vcf.gz", + "NA12878_chr21.ligate.vcf.gz.csi", + "VcfFile [chromosomes=[chr21], sampleCount=1, variantCount=836, phased=true, phasedAutodetect=true]", + [ + "NA12878" + ], + "76106bc8377b38cb64e1aa069c196a0d" + ], + [ + { + "id": "NA12878", + "chr": "chr22" + }, + "NA12878_chr22.ligate.vcf.gz", + "NA12878_chr22.ligate.vcf.gz.csi", + "VcfFile [chromosomes=[chr22], sampleCount=1, variantCount=903, phased=true, phasedAutodetect=true]", + [ + "NA12878" + ], + "a0615a8a5ce53f496ac691c5fc82a44" + ] + ], + [ + { + "VCF_IMPUTE_MINIMAC4:MINIMAC4_COMPRESSREF": { + "minimac4": "4.1.6" + } + }, + { + "VCF_IMPUTE_MINIMAC4:BCFTOOLS_INDEX_LIGATE": { + "bcftools": 1.22 + } + }, + { + "VCF_IMPUTE_MINIMAC4:MINIMAC4_IMPUTE": { + "minimac4": "4.1.6" + } + }, + { + "VCF_IMPUTE_MINIMAC4:GLIMPSE2_LIGATE": { + "glimpse2": "2.0.0" + } + }, + { + "VCF_IMPUTE_MINIMAC4:BCFTOOLS_INDEX_PHASE": { + "bcftools": 1.22 + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-12-11T11:59:37.554479908" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/vcf_impute_minimac4/tests/nextflow.config b/subworkflows/nf-core/vcf_impute_minimac4/tests/nextflow.config new file mode 100644 index 000000000000..fb03a534f208 --- /dev/null +++ b/subworkflows/nf-core/vcf_impute_minimac4/tests/nextflow.config @@ -0,0 +1,21 @@ +process { + withName: MINIMAC4_COMPRESSREF { + ext.args = '' + } + withName: MINIMAC4_IMPUTE { + ext.prefix = { "${meta.id}_${meta.chr}_${meta.regionout}.minimac4" } + ext.args = '--output-format vcf.gz' + } + + withName: GLIMPSE2_LIGATE { + ext.prefix = { "${meta.id}_${meta.chr}.ligate" } + } + + withName: BCFTOOLS_INDEX_PHASE { + ext.args = '--tbi' + } + + withName: BCFTOOLS_INDEX_LIGATE { + ext.args = '--csi' + } +} From 1e8cb1860404a3fe3ccca5526ceefca05f0f0a61 Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Thu, 11 Dec 2025 19:31:09 +0000 Subject: [PATCH 68/83] Add BBSplit stats to MultiQC in fastq_qc_trim_filter_setstrandedness subworkflow (#9559) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add BBSplit stats to MultiQC files in fastq_qc_trim_filter_setstrandedness Pass BBSplit stats output to MultiQC for visualization of read binning statistics. MultiQC 1.33+ includes support for parsing BBSplit stats.txt files and displaying per-sample read distribution across reference genomes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 --- .../nf-core/fastq_qc_trim_filter_setstrandedness/main.nf | 1 + 1 file changed, 1 insertion(+) diff --git a/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/main.nf b/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/main.nf index 84a029b30754..1ebada6e0d2e 100644 --- a/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/main.nf +++ b/subworkflows/nf-core/fastq_qc_trim_filter_setstrandedness/main.nf @@ -257,6 +257,7 @@ workflow FASTQ_QC_TRIM_FILTER_SETSTRANDEDNESS { BBMAP_BBSPLIT.out.primary_fastq.set { ch_filtered_reads } ch_versions = ch_versions.mix(BBMAP_BBSPLIT.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix(BBMAP_BBSPLIT.out.stats) if (!skip_linting) { FQ_LINT_AFTER_BBSPLIT( From 51ffcb629617b99c58d55d0ad07ce7c306cc5261 Mon Sep 17 00:00:00 2001 From: Evangelos Karatzas <32259775+vagkaratzas@users.noreply.github.com> Date: Fri, 12 Dec 2025 08:16:34 +0000 Subject: [PATCH 69/83] Update cutadapt (#9551) * proper stub for gz and stub test added * topic output syntax and tests update * meta yml updated with topics and ontologies * meta file curated * version bump to latest * update nf-tests properly * adding self to maintainers * removed Z flag as is deprecated after v4.10 * conda bug with different pre-built python version fixed --- modules/nf-core/cutadapt/environment.yml | 2 +- modules/nf-core/cutadapt/main.nf | 30 ++-- modules/nf-core/cutadapt/meta.yml | 57 +++++--- modules/nf-core/cutadapt/tests/main.nf.test | 58 +++++--- .../nf-core/cutadapt/tests/main.nf.test.snap | 131 ++++++++++++++---- 5 files changed, 200 insertions(+), 78 deletions(-) diff --git a/modules/nf-core/cutadapt/environment.yml b/modules/nf-core/cutadapt/environment.yml index b1ebb92747c5..cf84fbfa0069 100644 --- a/modules/nf-core/cutadapt/environment.yml +++ b/modules/nf-core/cutadapt/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::cutadapt=5.0 + - bioconda::cutadapt=5.2 diff --git a/modules/nf-core/cutadapt/main.nf b/modules/nf-core/cutadapt/main.nf index 84d97d4de868..c1f8a9a4ee68 100644 --- a/modules/nf-core/cutadapt/main.nf +++ b/modules/nf-core/cutadapt/main.nf @@ -3,9 +3,9 @@ process CUTADAPT { label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/17/1758869538eb8e658077cc14cd7a4e76fd9b6d73d3a68f85a70bf292e39e27c5/data' : - 'community.wave.seqera.io/library/cutadapt:5.0--991bbd2e184b7014' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/cutadapt:5.2--py311haab0aaa_0' : + 'biocontainers/cutadapt:5.2--py311haab0aaa_0'}" input: tuple val(meta), path(reads) @@ -13,7 +13,7 @@ process CUTADAPT { output: tuple val(meta), path('*.trim.fastq.gz'), emit: reads tuple val(meta), path('*.log') , emit: log - path "versions.yml" , emit: versions + tuple val("${task.process}"), val("cutadapt"), eval('cutadapt --version'), topic: versions, emit: versions_cutadapt when: task.ext.when == null || task.ext.when @@ -24,28 +24,24 @@ process CUTADAPT { def trimmed = meta.single_end ? "-o ${prefix}.trim.fastq.gz" : "-o ${prefix}_1.trim.fastq.gz -p ${prefix}_2.trim.fastq.gz" """ cutadapt \\ - -Z \\ --cores $task.cpus \\ $args \\ $trimmed \\ $reads \\ > ${prefix}.cutadapt.log - cat <<-END_VERSIONS > versions.yml - "${task.process}": - cutadapt: \$(cutadapt --version) - END_VERSIONS """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" - def trimmed = meta.single_end ? "${prefix}.trim.fastq.gz" : "${prefix}_1.trim.fastq.gz ${prefix}_2.trim.fastq.gz" + def prefix = task.ext.prefix ?: "${meta.id}" + if (meta.single_end) { + output_command = "echo '' | gzip > ${prefix}.trim.fastq.gz ;" + } + else { + output_command = "echo '' | gzip > ${prefix}_1.trim.fastq.gz ;" + output_command += "echo '' | gzip > ${prefix}_2.trim.fastq.gz ;" + } """ + ${output_command} touch ${prefix}.cutadapt.log - touch ${trimmed} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - cutadapt: \$(cutadapt --version) - END_VERSIONS """ } diff --git a/modules/nf-core/cutadapt/meta.yml b/modules/nf-core/cutadapt/meta.yml index 86179a570c34..a4717b56a2c1 100644 --- a/modules/nf-core/cutadapt/meta.yml +++ b/modules/nf-core/cutadapt/meta.yml @@ -1,18 +1,22 @@ name: cutadapt -description: Perform adapter/quality trimming on sequencing reads +description: Removes adapter sequences from sequencing reads keywords: + - adapter + - primers + - poly-A tails - trimming - - adapter trimming - - adapters - - quality trimming + - fastq tools: - - cuatadapt: + - cutadapt: description: | - Cutadapt finds and removes adapter sequences, primers, poly-A tails and other types of unwanted sequence from your high-throughput sequencing reads. - documentation: https://cutadapt.readthedocs.io/en/stable/index.html + Cutadapt finds and removes adapter sequences, primers, poly-A tails + and other types of unwanted sequence from your high-throughput sequencing reads. + homepage: https://cutadapt.readthedocs.io/en/stable/index.html + documentation: https://github.com/marcelm/cutadapt doi: 10.14806/ej.17.1.200 licence: ["MIT"] identifier: biotools:cutadapt + input: - - meta: type: map @@ -24,7 +28,9 @@ input: description: | List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. - ontologies: [] + pattern: "*.{fq,fastq,fq.gz,fastq.gz}" + ontologies: + - edam: "http://edamontology.org/format_1930" # FASTQ output: reads: - - meta: @@ -37,6 +43,7 @@ output: description: The trimmed/modified fastq reads pattern: "*fastq.gz" ontologies: + - edam: "http://edamontology.org/format_1930" # FASTQ - edam: http://edamontology.org/format_3989 # GZIP format log: - - meta: @@ -46,19 +53,37 @@ output: e.g. [ id:'test', single_end:false ] - "*.log": type: file - description: cuatadapt log file + description: cutadapt log file pattern: "*cutadapt.log" - ontologies: [] + ontologies: + - edam: "http://edamontology.org/format_2330" # Textual format + versions_cutadapt: + - - ${task.process}: + type: string + description: The name of the process + - cutadapt: + type: string + description: The name of the tool + - cutadapt --version: + type: eval + description: The expression to obtain the version of the tool + +topics: versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - - ${task.process}: + type: string + description: The name of the process + - cutadapt: + type: string + description: The name of the tool + - cutadapt --version: + type: eval + description: The expression to obtain the version of the tool + authors: - "@drpatelh" - "@kevinmenden" maintainers: - "@drpatelh" - "@kevinmenden" + - "@vagkaratzas" diff --git a/modules/nf-core/cutadapt/tests/main.nf.test b/modules/nf-core/cutadapt/tests/main.nf.test index 36927bd7fbec..0e3f7fefc88d 100644 --- a/modules/nf-core/cutadapt/tests/main.nf.test +++ b/modules/nf-core/cutadapt/tests/main.nf.test @@ -3,16 +3,14 @@ nextflow_process { name "Test Process CUTADAPT" script "../main.nf" process "CUTADAPT" + tag "modules" tag "modules_nfcore" tag "cutadapt" - test("sarscov2 Illumina single end [fastq]") { + test("sarscov2 - fastq - single-end") { when { - params { - outdir = "$outputDir" - } process { """ input[0] = [ @@ -28,20 +26,18 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert process.out.reads != null }, - { assert process.out.reads.get(0).get(1) ==~ ".*.trim.fastq.gz" }, - { assert snapshot(process.out.versions).match("versions_single_end") }, - { assert snapshot(path(process.out.reads.get(0).get(1)).linesGzip[0]).match() } + { assert snapshot( + process.out.reads, + file(process.out.log[0][1]).readLines()[1..10], // python versions differ in the default conda env and container + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } ) } } - test("sarscov2 Illumina paired-end [fastq]") { + test("sarscov2 - fastq - paired-end") { when { - params { - outdir = "$outputDir" - } process { """ input[0] = [ @@ -58,11 +54,39 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert process.out.reads != null }, - { assert process.out.reads.get(0).get(1).get(0) ==~ ".*.1.trim.fastq.gz" }, - { assert process.out.reads.get(0).get(1).get(1) ==~ ".*.2.trim.fastq.gz" }, - { assert snapshot(path(process.out.reads.get(0).get(1).get(1)).linesGzip[0]).match() }, - { assert snapshot(process.out.versions).match("versions_paired_end") } + { assert snapshot( + process.out.reads, + file(process.out.log[0][1]).readLines()[1..14], // python versions differ in the default conda env and container + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } + ) + } + } + + test("sarscov2 - fastq - single-end - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id: 'test', single_end:true ], + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ] + ] + """ + } + } + + then { + assertAll ( + { assert snapshot( + process.out.reads, + process.out.log, + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } ) } } diff --git a/modules/nf-core/cutadapt/tests/main.nf.test.snap b/modules/nf-core/cutadapt/tests/main.nf.test.snap index 6817ac229ba2..baf5c4a2ab12 100644 --- a/modules/nf-core/cutadapt/tests/main.nf.test.snap +++ b/modules/nf-core/cutadapt/tests/main.nf.test.snap @@ -1,46 +1,123 @@ { - "sarscov2 Illumina single end [fastq]": { + "sarscov2 - fastq - single-end - stub": { "content": [ - "@ERR5069949.2151832 NS500628:121:HK3MMAFX2:2:21208:10793:15304/1" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-03-06T10:27:15.235936866" - }, - "sarscov2 Illumina paired-end [fastq]": { - "content": [ - "@ERR5069949.2151832 NS500628:121:HK3MMAFX2:2:21208:10793:15304/2" + [ + [ + { + "id": "test", + "single_end": true + }, + "test.trim.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.cutadapt.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + { + "versions_cutadapt": [ + [ + "CUTADAPT", + "cutadapt", + "5.2" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-03-06T10:27:24.38468252" + "timestamp": "2025-12-11T12:48:07.964157954" }, - "versions_paired_end": { + "sarscov2 - fastq - paired-end": { "content": [ [ - "versions.yml:md5,8428231c6f665759beec10b0aba11075" - ] + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.trim.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec", + "test_2.trim.fastq.gz:md5,2ebae722295ea66d84075a3b042e2b42" + ] + ] + ], + [ + "Command line parameters: --cores 2 -o test_1.trim.fastq.gz -p test_2.trim.fastq.gz test_1.fastq.gz test_2.fastq.gz", + "Processing paired-end reads on 2 cores ...", + "", + "=== Summary ===", + "", + "Total read pairs processed: 100", + "Pairs written (passing filters): 100 (100.0%)", + "", + "Total basepairs processed: 27,645 bp", + " Read 1: 13,897 bp", + " Read 2: 13,748 bp", + "Total written (filtered): 27,645 bp (100.0%)", + " Read 1: 13,897 bp", + " Read 2: 13,748 bp" + ], + { + "versions_cutadapt": [ + [ + "CUTADAPT", + "cutadapt", + "5.2" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-04-01T10:51:18.715277676" + "timestamp": "2025-12-11T14:12:08.287985982" }, - "versions_single_end": { + "sarscov2 - fastq - single-end": { "content": [ [ - "versions.yml:md5,8428231c6f665759beec10b0aba11075" - ] + [ + { + "id": "test", + "single_end": true + }, + "test.trim.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + [ + "Command line parameters: --cores 2 -o test.trim.fastq.gz test_1.fastq.gz", + "Processing single-end reads on 2 cores ...", + "", + "=== Summary ===", + "", + "Total reads processed: 100", + "Reads written (passing filters): 100 (100.0%)", + "", + "Total basepairs processed: 13,897 bp", + "Total written (filtered): 13,897 bp (100.0%)" + ], + { + "versions_cutadapt": [ + [ + "CUTADAPT", + "cutadapt", + "5.2" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-04-01T10:51:14.492236529" + "timestamp": "2025-12-11T14:06:44.706447277" } } \ No newline at end of file From 4999717244c967641d5147400fbbeb63f88bf86d Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Fri, 12 Dec 2025 14:45:07 +0000 Subject: [PATCH 70/83] added cutadapt to stub now that stub gz is properly created, and removed cutadapt versions, since it is now ported to topics --- .../fastq_removeadapters_merge/main.nf | 1 - .../tests/main.nf.test | 2 +- .../tests/main.nf.test.snap | 37 +++++++++---------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index c20cb20ef823..fc6e174ccf20 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -55,7 +55,6 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { if (!skip_cutadapt) { CUTADAPT( ch_reads ) ch_reads = CUTADAPT.out.reads - ch_versions = ch_versions.mix(CUTADAPT.out.versions.first()) ch_multiqc_files = ch_multiqc_files.mix(CUTADAPT.out.log) } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index d937cfeb85db..463176667d3c 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -181,7 +181,7 @@ nextflow_workflow { ] input[1] = false // skip_trimmomatic - input[2] = true // skip_cutadapt + input[2] = false // skip_cutadapt input[3] = false // skip_trimgalore input[4] = false // skip_bbduk input[5] = [] // contaminants diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap index 675de50d3378..c0af6b24a249 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap @@ -33,6 +33,13 @@ }, "test.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" ], + [ + { + "id": "test", + "single_end": true + }, + "test.cutadapt.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ], [ { "id": "test", @@ -191,6 +198,13 @@ }, "test.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" ], + [ + { + "id": "test", + "single_end": true + }, + "test.cutadapt.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ], [ { "id": "test", @@ -276,7 +290,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-09T13:54:41.801054438" + "timestamp": "2025-12-12T14:39:53.946631816" }, "sarscov2 - fastq - paired-end": { "content": [ @@ -342,11 +356,6 @@ "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { "trimmomatic": 0.39 } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:CUTADAPT": { - "cutadapt": 5.0 - } } ] ], @@ -354,7 +363,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-09T13:54:32.103319027" + "timestamp": "2025-12-12T14:42:11.204624875" }, "sarscov2 - fastq - single-end": { "content": [ @@ -409,11 +418,6 @@ "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { "trimmomatic": 0.39 } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:CUTADAPT": { - "cutadapt": 5.0 - } } ] ], @@ -421,7 +425,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-09T13:54:18.384916548" + "timestamp": "2025-12-12T14:41:57.40696623" }, "sarscov2 - fastq - paired-end - no-merge": { "content": [ @@ -486,11 +490,6 @@ "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { "trimmomatic": 0.39 } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:CUTADAPT": { - "cutadapt": 5.0 - } } ] ], @@ -498,6 +497,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-09T14:28:19.369829207" + "timestamp": "2025-12-12T14:42:24.930358468" } } \ No newline at end of file From a0a14061a2be716b8f912311bf06bed6a50c4592 Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Fri, 12 Dec 2025 14:50:34 +0000 Subject: [PATCH 71/83] single-end test with tool skips --- .../tests/main.nf.test | 41 +++++++++++++++++++ .../tests/main.nf.test.snap | 32 +++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index 463176667d3c..86637babc1ab 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -164,6 +164,47 @@ nextflow_workflow { } } + test("sarscov2 - fastq - single-end - with-skips") { + when { + params { + save_merged = false + } + workflow { + """ + input[0] = [ + [ id:'test', single_end:true ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ] + + input[1] = true // skip_trimmomatic + input[2] = false // skip_cutadapt + input[3] = true // skip_trimgalore + input[4] = false // skip_bbduk + input[5] = [] // contaminants + input[6] = true // skip_leehom + input[7] = false // skip_fastp + input[8] = false // fastp_discard_trimmed_pass + input[9] = true // fastp_save_trimmed_fail + input[10] = params.save_merged + input[11] = true // skip_adapterremoval + input[12] = [] // text adapters + """ + } + } + + then { + assert workflow.success + assert snapshot( + workflow.out.reads[0][1], + workflow.out.discarded_reads.collect { file(it[1]).name }, + file(workflow.out.fastp_html[0][1]).name, + path(workflow.out.fastp_log[0][1]).readLines().size(), + workflow.out.multiqc_files.collect { file(it[1]).name }, + workflow.out.versions.collect { path(it).yaml } + ).match() + } + } + test("sarscov2 - fastq - single-end - stub") { options "-stub" diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap index c0af6b24a249..1bc57e13618c 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap @@ -1,4 +1,36 @@ { + "sarscov2 - fastq - single-end - with-skips": { + "content": [ + "test.fastp.fastq.gz:md5,e051aedfa286d0567c83870d93ed93a3", + [ + "test.fail.fastq.gz" + ], + "test.fastp.html", + 32, + [ + "test.bbduk.log", + "test.cutadapt.log", + "test.fastp.json" + ], + [ + { + "FASTQ_REMOVEADAPTERS_MERGE:FASTP": { + "fastp": "1.0.1" + } + }, + { + "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { + "bbmap": 39.18 + } + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-12T14:49:19.909628033" + }, "sarscov2 - fastq - single-end - stub": { "content": [ { From 54a78b64c3b4cff96180a54ebae5a989abbaf8d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Sat, 13 Dec 2025 10:49:06 +0100 Subject: [PATCH 72/83] Standarize and alignment for all imputation and alignment modules (#9566) * Standarize and alignment * Fix glimpse2 sbwf test * Fix test * Add comment * Update snapshot --------- Co-authored-by: LouisLeNezet --- modules/nf-core/bcftools/index/main.nf | 2 - modules/nf-core/beagle5/beagle/main.nf | 28 ++-- modules/nf-core/glimpse/chunk/main.nf | 24 ++-- .../glimpse/chunk/tests/nextflow.config | 2 +- modules/nf-core/glimpse/concordance/main.nf | 29 ++-- modules/nf-core/glimpse/ligate/main.nf | 14 +- modules/nf-core/glimpse/phase/main.nf | 40 +++--- modules/nf-core/glimpse/sample/main.nf | 14 +- modules/nf-core/glimpse2/chunk/main.nf | 30 ++--- .../glimpse2/chunk/tests/nextflow.config | 6 +- modules/nf-core/glimpse2/concordance/main.nf | 39 +++--- .../concordance/tests/nextflow.config | 2 +- modules/nf-core/glimpse2/ligate/main.nf | 14 +- modules/nf-core/glimpse2/phase/main.nf | 81 ++++++------ .../nf-core/glimpse2/phase/tests/main.nf.test | 2 - .../glimpse2/phase/tests/nextflow.config | 6 +- .../nf-core/glimpse2/splitreference/main.nf | 37 +++--- .../splitreference/tests/nextflow.config | 4 +- modules/nf-core/minimac4/compressref/main.nf | 14 +- modules/nf-core/minimac4/impute/main.nf | 22 ++-- .../minimac4/impute/tests/nextflow.config | 4 +- modules/nf-core/quilt/quilt/main.nf | 85 ++++++------ .../nf-core/quilt/quilt/tests/nextflow.config | 8 +- modules/nf-core/shapeit5/ligate/main.nf | 19 +-- .../shapeit5/ligate/tests/nextflow.config | 2 +- modules/nf-core/shapeit5/phasecommon/main.nf | 51 +++---- .../phasecommon/tests/nextflow.config | 2 +- modules/nf-core/shapeit5/phaserare/main.nf | 43 +++--- .../shapeit5/phaserare/tests/nextflow.config | 4 +- modules/nf-core/shapeit5/switch/main.nf | 40 +++--- .../shapeit5/switch/tests/nextflow.config | 2 +- modules/nf-core/stitch/main.nf | 50 +++---- modules/nf-core/stitch/tests/main.nf.test | 4 +- .../nf-core/stitch/tests/main.nf.test.snap | 3 +- modules/nf-core/stitch/tests/nextflow.config | 4 +- subworkflows/nf-core/bam_impute_quilt/main.nf | 59 ++++----- .../bam_impute_quilt/tests/nextflow.config | 6 +- .../nf-core/bam_impute_stitch/main.nf | 81 ++++++------ .../bam_impute_stitch/tests/main.nf.test.snap | 54 ++++---- .../bam_impute_stitch/tests/nextflow.config | 10 +- .../nf-core/bam_vcf_impute_glimpse2/main.nf | 124 ++++++++++-------- .../tests/main.nf.test | 20 +-- .../tests/main.nf.test.snap | 96 +++++++------- .../tests/nextflow.config | 30 ++--- .../nf-core/vcf_impute_beagle5/main.nf | 76 ++++++----- .../tests/main.nf.test.snap | 36 ++--- .../vcf_impute_beagle5/tests/nextflow.config | 10 +- .../nf-core/vcf_impute_glimpse/main.nf | 78 +++++------ .../vcf_impute_glimpse/tests/main.nf.test | 4 +- .../tests/main.nf.test.snap | 2 +- .../vcf_impute_glimpse/tests/nextflow.config | 4 +- .../nf-core/vcf_impute_minimac4/main.nf | 24 ++-- .../nf-core/vcf_phase_shapeit5/main.nf | 43 +++--- .../tests/main.nf.test.snap | 36 ++--- .../vcf_phase_shapeit5/tests/nextflow.config | 6 +- 55 files changed, 785 insertions(+), 745 deletions(-) diff --git a/modules/nf-core/bcftools/index/main.nf b/modules/nf-core/bcftools/index/main.nf index 16ff775a00d4..ad1feb1c04fc 100644 --- a/modules/nf-core/bcftools/index/main.nf +++ b/modules/nf-core/bcftools/index/main.nf @@ -20,7 +20,6 @@ process BCFTOOLS_INDEX { script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" """ bcftools \\ @@ -37,7 +36,6 @@ process BCFTOOLS_INDEX { stub: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" def extension = args.contains("--tbi") || args.contains("-t") ? "tbi" : "csi" """ diff --git a/modules/nf-core/beagle5/beagle/main.nf b/modules/nf-core/beagle5/beagle/main.nf index e66c9e40b019..b9b21554e73f 100644 --- a/modules/nf-core/beagle5/beagle/main.nf +++ b/modules/nf-core/beagle5/beagle/main.nf @@ -1,11 +1,11 @@ process BEAGLE5_BEAGLE { - tag "$meta.id" + tag "${meta.id}" label 'process_high' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/beagle:5.5_27Feb25.75f--hdfd78af_0': - 'biocontainers/beagle:5.5_27Feb25.75f--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/beagle:5.5_27Feb25.75f--hdfd78af_0' + : 'biocontainers/beagle:5.5_27Feb25.75f--hdfd78af_0'}" input: // Including `val(region)` to prevent errors with multi-chromosome VCFs and single-chromosome reference panels. @@ -21,26 +21,28 @@ process BEAGLE5_BEAGLE { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}.bglout" - def ref_command = refpanel ? "ref=$refpanel" : "" - def map_command = genmap ? "map=$genmap" : "" - def region_cmd = region ? "chrom=$region" : "" - def excludesamples_command = exclsamples ? "excludesamples=$exclsamples" : "" - def excludemarkers_command = exclmarkers ? "excludemarkers=$exclmarkers" : "" + + def ref_command = refpanel ? "ref=${refpanel}" : "" + def map_command = genmap ? "map=${genmap}" : "" + def region_cmd = region ? "chrom=${region}" : "" + + def excludesamples_command = exclsamples ? "excludesamples=${exclsamples}" : "" + def excludemarkers_command = exclmarkers ? "excludemarkers=${exclmarkers}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[beagle] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' + log.info('[beagle] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') } else { - avail_mem = (task.memory.mega*0.8).intValue() + avail_mem = (task.memory.mega * 0.8).intValue() } """ beagle -Xmx${avail_mem}M \\ gt=${vcf} \\ out=${prefix} \\ - $args \\ + ${args} \\ ${ref_command} \\ ${map_command} \\ ${region_cmd} \\ diff --git a/modules/nf-core/glimpse/chunk/main.nf b/modules/nf-core/glimpse/chunk/main.nf index c8d92f472997..aead3b96af51 100644 --- a/modules/nf-core/glimpse/chunk/main.nf +++ b/modules/nf-core/glimpse/chunk/main.nf @@ -1,32 +1,32 @@ process GLIMPSE_CHUNK { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/glimpse-bio:1.1.1--h2ce4488_2': - 'biocontainers/glimpse-bio:1.1.1--hce55b13_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/glimpse-bio:1.1.1--h2ce4488_2' + : 'biocontainers/glimpse-bio:1.1.1--hce55b13_1'}" input: tuple val(meta), path(input), path(input_index), val(region) output: tuple val(meta), path("*.txt"), emit: chunk_chr - path "versions.yml" , emit: versions + path "versions.yml", emit: versions when: task.ext.when == null || task.ext.when script: - def prefix = task.ext.prefix ?: "${meta.id}" - def args = task.ext.args ?: "" + def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: "" """ GLIMPSE_chunk \\ - $args \\ - --input $input \\ - --region $region \\ - --thread $task.cpus \\ + ${args} \\ + --input ${input} \\ + --region ${region} \\ + --thread ${task.cpus} \\ --output ${prefix}.txt cat <<-END_VERSIONS > versions.yml @@ -36,7 +36,7 @@ process GLIMPSE_CHUNK { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.txt diff --git a/modules/nf-core/glimpse/chunk/tests/nextflow.config b/modules/nf-core/glimpse/chunk/tests/nextflow.config index 8f4c838e95c4..21c77a9fab77 100644 --- a/modules/nf-core/glimpse/chunk/tests/nextflow.config +++ b/modules/nf-core/glimpse/chunk/tests/nextflow.config @@ -1,6 +1,6 @@ process { withName: GLIMPSE_CHUNK { - ext.args = { "${params.glimpse_args}" } + ext.args = { "${params.glimpse_args}" } ext.prefix = { "${meta.id}" } } } diff --git a/modules/nf-core/glimpse/concordance/main.nf b/modules/nf-core/glimpse/concordance/main.nf index 4a70a6afffed..045582e69b66 100644 --- a/modules/nf-core/glimpse/concordance/main.nf +++ b/modules/nf-core/glimpse/concordance/main.nf @@ -1,17 +1,17 @@ process GLIMPSE_CONCORDANCE { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/glimpse-bio:1.1.1--h0303221_3': - 'biocontainers/glimpse-bio:1.1.1--h0303221_3' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/glimpse-bio:1.1.1--h0303221_3' + : 'biocontainers/glimpse-bio:1.1.1--h0303221_3'}" input: tuple val(meta), path(estimate), path(estimate_index), path(freq), path(freq_index), path(truth), path(truth_index), val(region) - val(min_prob) - val(min_dp) - val(bins) + val min_prob + val min_dp + val bins output: tuple val(meta), path("*.error.cal.txt.gz") , emit: errors_cal @@ -20,6 +20,7 @@ process GLIMPSE_CONCORDANCE { tuple val(meta), path("*.rsquare.grp.txt.gz"), emit: rsquare_grp tuple val(meta), path("*.rsquare.spl.txt.gz"), emit: rsquare_spl path "versions.yml" , emit: versions + when: task.ext.when == null || task.ext.when @@ -30,15 +31,15 @@ process GLIMPSE_CONCORDANCE { def min_dp_cmd = min_dp ? "--minDP ${min_dp}" : "--minDP 8" def bins_cmd = bins ? "--bins ${bins}" : "--bins 0.00000 0.00100 0.00200 0.00500 0.01000 0.05000 0.10000 0.20000 0.50000" """ - echo $region $freq $truth $estimate > input.txt + echo ${region} ${freq} ${truth} ${estimate} > input.txt GLIMPSE_concordance \\ - $args \\ + ${args} \\ --input input.txt \\ - --thread $task.cpus \\ + --thread ${task.cpus} \\ --output ${prefix} \\ - $min_prob_cmd \\ - $min_dp_cmd \\ - $bins_cmd + ${min_prob_cmd} \\ + ${min_dp_cmd} \\ + ${bins_cmd} cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -47,7 +48,7 @@ process GLIMPSE_CONCORDANCE { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: "${meta.id}" """ echo "" | gzip > ${prefix}.error.cal.txt.gz diff --git a/modules/nf-core/glimpse/ligate/main.nf b/modules/nf-core/glimpse/ligate/main.nf index 885f5d5ddd5e..f60db9d6efa0 100644 --- a/modules/nf-core/glimpse/ligate/main.nf +++ b/modules/nf-core/glimpse/ligate/main.nf @@ -1,11 +1,11 @@ process GLIMPSE_LIGATE { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/glimpse-bio:1.1.1--hce55b13_1': - 'biocontainers/glimpse-bio:1.1.1--hce55b13_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/glimpse-bio:1.1.1--hce55b13_1' + : 'biocontainers/glimpse-bio:1.1.1--hce55b13_1'}" input: tuple val(meta), path(input_list), path(input_index) @@ -22,12 +22,12 @@ process GLIMPSE_LIGATE { def prefix = task.ext.prefix ?: "${meta.id}" def suffix = task.ext.suffix ?: "vcf.gz" """ - printf "%s\\n" $input_list | tr -d '[],' | sort -V > all_files.txt + printf "%s\\n" ${input_list} | tr -d '[],' | sort -V > all_files.txt GLIMPSE_ligate \\ - $args \\ + ${args} \\ --input all_files.txt \\ - --thread $task.cpus \\ + --thread ${task.cpus} \\ --output ${prefix}.${suffix} cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/glimpse/phase/main.nf b/modules/nf-core/glimpse/phase/main.nf index e5ba79718880..e695ced05589 100644 --- a/modules/nf-core/glimpse/phase/main.nf +++ b/modules/nf-core/glimpse/phase/main.nf @@ -1,40 +1,40 @@ process GLIMPSE_PHASE { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/glimpse-bio:1.1.1--hce55b13_1': - 'biocontainers/glimpse-bio:1.1.1--hce55b13_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/glimpse-bio:1.1.1--hce55b13_1' + : 'biocontainers/glimpse-bio:1.1.1--hce55b13_1'}" input: - tuple val(meta) , path(input), path(input_index), path(samples_file), val(input_region), val(output_region), path(reference), path(reference_index), path(map) + tuple val(meta), path(input), path(input_index), path(samples_file), val(input_region), val(output_region), path(reference), path(reference_index), path(map) output: - tuple val(meta), path("*.{vcf,bcf,vcf.gz,bcf.gz}"), emit: phased_variants - path "versions.yml" , emit: versions + tuple val(meta), path("*.{vcf,bcf,vcf.gz,bcf.gz}"), emit: phased_variants + path "versions.yml" , emit: versions when: - task.ext.when == null || task.ext.when + task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}_${input_region.replace(":","_")}" + def prefix = task.ext.prefix ?: "${meta.id}_${input_region.replace(":", "_")}" def suffix = task.ext.suffix ?: "vcf.gz" - def map_command = map ? "--map $map" :"" - def samples_file_command = samples_file ? "--samples-file $samples_file" :"" + def map_command = map ? "--map ${map}" : "" + def samples_file_command = samples_file ? "--samples-file ${samples_file}" : "" """ GLIMPSE_phase \\ - $args \\ - --input $input \\ - --reference $reference \\ - $map_command \\ - $samples_file_command \\ - --input-region $input_region \\ - --output-region $output_region \\ - --thread $task.cpus \\ + ${args} \\ + --input ${input} \\ + --reference ${reference} \\ + ${map_command} \\ + ${samples_file_command} \\ + --input-region ${input_region} \\ + --output-region ${output_region} \\ + --thread ${task.cpus} \\ --output ${prefix}.${suffix} cat <<-END_VERSIONS > versions.yml @@ -44,7 +44,7 @@ process GLIMPSE_PHASE { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}_${input_region.replace(":","_")}" + def prefix = task.ext.prefix ?: "${meta.id}_${input_region.replace(":", "_")}" def suffix = task.ext.suffix ?: "vcf.gz" """ diff --git a/modules/nf-core/glimpse/sample/main.nf b/modules/nf-core/glimpse/sample/main.nf index 0fcfb6b4f2f9..9198732d2dac 100644 --- a/modules/nf-core/glimpse/sample/main.nf +++ b/modules/nf-core/glimpse/sample/main.nf @@ -1,11 +1,11 @@ process GLIMPSE_SAMPLE { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/glimpse-bio:1.1.1--hce55b13_1': - 'biocontainers/glimpse-bio:1.1.1--hce55b13_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/glimpse-bio:1.1.1--hce55b13_1' + : 'biocontainers/glimpse-bio:1.1.1--hce55b13_1'}" input: tuple val(meta), path(input), path(index) @@ -24,9 +24,9 @@ process GLIMPSE_SAMPLE { """ GLIMPSE_sample \\ - $args \\ - --input $input \\ - --thread $task.cpus \\ + ${args} \\ + --input ${input} \\ + --thread ${task.cpus} \\ --output ${prefix}.${suffix} cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/glimpse2/chunk/main.nf b/modules/nf-core/glimpse2/chunk/main.nf index 16e361eef034..fd65613d92ac 100644 --- a/modules/nf-core/glimpse2/chunk/main.nf +++ b/modules/nf-core/glimpse2/chunk/main.nf @@ -1,8 +1,8 @@ process GLIMPSE2_CHUNK { - tag "$meta.id" + tag "${meta.id}" label 'process_low' - beforeScript """ + beforeScript """ if cat /proc/cpuinfo | grep avx2 -q then echo "Feature AVX2 present on host" @@ -12,13 +12,13 @@ process GLIMPSE2_CHUNK { fi """ conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/glimpse-bio:2.0.1--h46b9e50_1': - 'biocontainers/glimpse-bio:2.0.1--h46b9e50_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/glimpse-bio:2.0.1--h46b9e50_1' + : 'biocontainers/glimpse-bio:2.0.1--h46b9e50_1'}" input: tuple val(meta), path(input), path(input_index), val(region), path(map) - val(model) + val model output: tuple val(meta), path("*.txt"), emit: chunk_chr @@ -28,18 +28,18 @@ process GLIMPSE2_CHUNK { task.ext.when == null || task.ext.when script: - def prefix = task.ext.prefix ?: "${meta.id}" - def args = task.ext.args ?: "" - def map_cmd = map ? "--map ${map}":"" + def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: "" + def map_cmd = map ? "--map ${map}" : "" """ GLIMPSE2_chunk \\ - $args \\ - $map_cmd \\ + ${args} \\ + ${map_cmd} \\ --${model} \\ - --input $input \\ - --region $region \\ - --threads $task.cpus \\ + --input ${input} \\ + --region ${region} \\ + --threads ${task.cpus} \\ --output ${prefix}.txt cat <<-END_VERSIONS > versions.yml @@ -49,7 +49,7 @@ process GLIMPSE2_CHUNK { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: "${meta.id}" """ echo "${meta.id}\t${region}\t0\t0\t0\t0\t0\t0" > ${prefix}.txt diff --git a/modules/nf-core/glimpse2/chunk/tests/nextflow.config b/modules/nf-core/glimpse2/chunk/tests/nextflow.config index adaa0b252987..3684f001f4e2 100644 --- a/modules/nf-core/glimpse2/chunk/tests/nextflow.config +++ b/modules/nf-core/glimpse2/chunk/tests/nextflow.config @@ -1,14 +1,14 @@ process { withName: GLIMPSE2_CHUNK { - // Necessary to work on a small region - ext.args = [ + ext.args = [ "--seed 1", "--window-mb 0.01", "--window-cm 0.01", "--window-count 200", "--buffer-mb 0.005", "--buffer-cm 0.005", - "--buffer-count 30"].join(' ') + "--buffer-count 30", + ].join(' ') ext.prefix = { "${meta.id}" } } } diff --git a/modules/nf-core/glimpse2/concordance/main.nf b/modules/nf-core/glimpse2/concordance/main.nf index 945c3dd6a0e4..d343ae407c7c 100644 --- a/modules/nf-core/glimpse2/concordance/main.nf +++ b/modules/nf-core/glimpse2/concordance/main.nf @@ -1,11 +1,11 @@ process GLIMPSE2_CONCORDANCE { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/glimpse-bio:2.0.1--h46b9e50_1': - 'biocontainers/glimpse-bio:2.0.1--h46b9e50_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/glimpse-bio:2.0.1--h46b9e50_1' + : 'biocontainers/glimpse-bio:2.0.1--h46b9e50_1'}" input: tuple val(meta), path(estimate), path(estimate_index), path(truth), path(truth_index), path(freq), path(freq_index), path(samples), val(region) @@ -35,26 +35,28 @@ process GLIMPSE2_CONCORDANCE { def min_val_dp_cmd = min_val_dp ? "--min-val-dp ${min_val_dp}" : "" def region_str = region instanceof List ? region.join('\\n') : region - if (((groups ? 1:0) + (bins ? 1:0) + (ac_bins ? 1:0) + (allele_counts ? 1:0)) != 1) error "One and only one argument should be selected between groups, bins, ac_bins, allele_counts" + if (((groups ? 1 : 0) + (bins ? 1 : 0) + (ac_bins ? 1 : 0) + (allele_counts ? 1 : 0)) != 1) { + error("One and only one argument should be selected between groups, bins, ac_bins, allele_counts") + } if (args.contains("--gt-val")) { assert !(min_val_gl || min_val_dp) : "If --gt-val is set, --min-val-gl nor --min-val-dp must be set" } """ - printf '$region_str' > regions.txt - sed 's/\$/ $freq $truth $estimate/' regions.txt > input.txt + printf '${region_str}' > regions.txt + sed 's/\$/ ${freq} ${truth} ${estimate}/' regions.txt > input.txt GLIMPSE2_concordance \\ - $args \\ - $samples_cmd \\ - $groups_cmd \\ - $bins_cmd \\ - $ac_bins_cmd \\ - $ale_ct_cmd \\ - $min_val_gl_cmd \\ - $min_val_dp_cmd \\ + ${args} \\ + ${samples_cmd} \\ + ${groups_cmd} \\ + ${bins_cmd} \\ + ${ac_bins_cmd} \\ + ${ale_ct_cmd} \\ + ${min_val_gl_cmd} \\ + ${min_val_dp_cmd} \\ --input input.txt \\ - --thread $task.cpus \\ + --thread ${task.cpus} \\ --output ${prefix} cat <<-END_VERSIONS > versions.yml @@ -64,8 +66,9 @@ process GLIMPSE2_CONCORDANCE { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" - def args = task.ext.args ?: "" + def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: "" + def rsquare_per_site_cmd = args.contains("--out-r2-per-site") ? "touch ${prefix}_r2_sites.txt.gz" : "" """ echo "" | gzip > ${prefix}.error.cal.txt.gz diff --git a/modules/nf-core/glimpse2/concordance/tests/nextflow.config b/modules/nf-core/glimpse2/concordance/tests/nextflow.config index df8f4f67a604..00b50dd49a63 100644 --- a/modules/nf-core/glimpse2/concordance/tests/nextflow.config +++ b/modules/nf-core/glimpse2/concordance/tests/nextflow.config @@ -1,6 +1,6 @@ process { withName: GLIMPSE2_CONCORDANCE { - ext.args = { params.glimpse2_concordance_args} + ext.args = { params.glimpse2_concordance_args } ext.prefix = { "${meta.id}" } } } diff --git a/modules/nf-core/glimpse2/ligate/main.nf b/modules/nf-core/glimpse2/ligate/main.nf index 40559de297b1..eea6141c9b34 100644 --- a/modules/nf-core/glimpse2/ligate/main.nf +++ b/modules/nf-core/glimpse2/ligate/main.nf @@ -1,11 +1,11 @@ process GLIMPSE2_LIGATE { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/glimpse-bio:2.0.1--h46b9e50_1': - 'biocontainers/glimpse-bio:2.0.1--h46b9e50_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/glimpse-bio:2.0.1--h46b9e50_1' + : 'biocontainers/glimpse-bio:2.0.1--h46b9e50_1'}" input: tuple val(meta), path(input_list), path(input_index) @@ -22,12 +22,12 @@ process GLIMPSE2_LIGATE { def prefix = task.ext.prefix ?: "${meta.id}" def suffix = task.ext.suffix ?: "vcf.gz" """ - printf "%s\\n" $input_list | tr -d '[],' | sort -V > all_files.txt + printf "%s\\n" ${input_list} | tr -d '[],' | sort -V > all_files.txt GLIMPSE2_ligate \\ - $args \\ + ${args} \\ --input all_files.txt \\ - --thread $task.cpus \\ + --thread ${task.cpus} \\ --output ${prefix}.${suffix} cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/glimpse2/phase/main.nf b/modules/nf-core/glimpse2/phase/main.nf index 05f8fbc266e2..d22fdde22cbd 100644 --- a/modules/nf-core/glimpse2/phase/main.nf +++ b/modules/nf-core/glimpse2/phase/main.nf @@ -1,8 +1,8 @@ process GLIMPSE2_PHASE { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' - beforeScript """ + beforeScript """ if cat /proc/cpuinfo | grep avx2 -q then echo "Feature AVX2 present on host" @@ -13,82 +13,83 @@ process GLIMPSE2_PHASE { """ conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/glimpse-bio:2.0.1--h46b9e50_1': - 'biocontainers/glimpse-bio:2.0.1--h46b9e50_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/glimpse-bio:2.0.1--h46b9e50_1' + : 'biocontainers/glimpse-bio:2.0.1--h46b9e50_1'}" input: - tuple val(meta) , path(input, arity: '1..*'), path(input_index), path(bamlist), path(samples_file), val(input_region), val(output_region), path(reference), path(reference_index), path(map) - tuple val(meta2), path(fasta_reference), path(fasta_reference_index) + tuple val(meta), path(input, arity: '1..*'), path(input_index), path(bamlist), path(samples_file), val(input_region), val(output_region), path(reference), path(reference_index), path(map) + tuple val(meta2), path(fasta_reference), path(fasta_reference_index) output: - tuple val(meta), path("*.{vcf,vcf.gz,bcf,bgen}"), emit: phased_variants - tuple val(meta), path("*.txt.gz") , emit: stats_coverage, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*.{vcf,vcf.gz,bcf,bgen}"), emit: phased_variants + tuple val(meta), path("*.txt.gz") , emit: stats_coverage, optional: true + path "versions.yml" , emit: versions when: - task.ext.when == null || task.ext.when + task.ext.when == null || task.ext.when script: - def region = input_region ? "${output_region.replace(":","_")}" : "${reference}" + def region = input_region ? "${output_region.replace(":", "_")}" : "${reference}" def args = task.ext.args ?: "" def prefix = task.ext.prefix ?: "${meta.id}_${region}" def suffix = task.ext.suffix ?: "vcf.gz" - def map_command = map ? "--map $map" : "" - def samples_file_command = samples_file ? "--samples-file $samples_file" : "" - def fasta_command = fasta_reference ? "--fasta $fasta_reference" : "" - def input_region_cmd = input_region ? "--input-region $input_region" : "" - def output_region_cmd = output_region ? "--output-region $output_region": "" + def map_command = map ? "--map ${map}" : "" + def samples_file_command = samples_file ? "--samples-file ${samples_file}" : "" + def fasta_command = fasta_reference ? "--fasta ${fasta_reference}" : "" + def input_region_cmd = input_region ? "--input-region ${input_region}" : "" + def output_region_cmd = output_region ? "--output-region ${output_region}" : "" - def input_type = input.collect{ - it.toString().endsWithAny("cram", "bam") ? "bam" : - it.toString().endsWithAny("vcf", "bcf", "vcf.gz") ? "gl" : + def input_type = input.collect{ + it.toString().endsWithAny("cram", "bam") ? "bam" : + it.toString().endsWithAny("vcf", "bcf", "vcf.gz") ? "gl" : it.getExtension() }.unique() if (input_type.size() > 1 | !(input_type.contains("gl") | input_type.contains("bam"))) { - error "Input files must be of the same type and either .bam/.cram or .vcf/.vcf.gz/.bcf format. Found: ${input_type}" - } else { + error("Input files must be of the same type and either .bam/.cram or .vcf/.vcf.gz/.bcf format. Found: ${input_type}") + } + else { input_type = input_type[0] } if (input_type == "gl" & input.size() > 1) { - error "Only one input .vcf/.vcf.gz/.bcf file can be provided" + error("Only one input .vcf/.vcf.gz/.bcf file can be provided") } def input_list = input.size() > 1 """ - if [ -n "$bamlist" ] ; + if [ -n "${bamlist}" ] ; then - input_command="--bam-list $bamlist" - elif $input_list ; + input_command="--bam-list ${bamlist}" + elif ${input_list} ; then ls -1 | grep '\\.cram\$\\|\\.bam\$' | sort > all_bam.txt input_command="--bam-list all_bam.txt" else - if [ "$input_type" == "bam" ]; + if [ "${input_type}" == "bam" ]; then - input_command="--bam-file $input" - elif [ "$input_type" == "gl" ]; + input_command="--bam-file ${input}" + elif [ "${input_type}" == "gl" ]; then - input_command="--input-gl $input" + input_command="--input-gl ${input}" else echo "Input file type not recognised" - echo "$input_type" + echo "${input_type}" exit 1 fi fi GLIMPSE2_phase \\ - $args \\ + ${args} \\ \$input_command \\ - --reference $reference \\ - $map_command \\ - $fasta_command \\ - $samples_file_command \\ - $input_region_cmd \\ - $output_region_cmd \\ - --thread $task.cpus \\ + --reference ${reference} \\ + ${map_command} \\ + ${fasta_command} \\ + ${samples_file_command} \\ + ${input_region_cmd} \\ + ${output_region_cmd} \\ + --thread ${task.cpus} \\ --output ${prefix}.${suffix} cat <<-END_VERSIONS > versions.yml @@ -98,7 +99,7 @@ process GLIMPSE2_PHASE { """ stub: - def region = input_region ? "${output_region.replace(":","_")}" : "${reference}" + def region = input_region ? "${output_region.replace(":", "_")}" : "${reference}" def prefix = task.ext.prefix ?: "${meta.id}_${region}" def suffix = task.ext.suffix ?: "vcf.gz" def create_cmd = suffix.endsWith(".gz") ? "echo | gzip > ${prefix}.${suffix}" : "touch ${prefix}.${suffix}" diff --git a/modules/nf-core/glimpse2/phase/tests/main.nf.test b/modules/nf-core/glimpse2/phase/tests/main.nf.test index c7dfcd7ed827..5475f308a581 100644 --- a/modules/nf-core/glimpse2/phase/tests/main.nf.test +++ b/modules/nf-core/glimpse2/phase/tests/main.nf.test @@ -179,7 +179,6 @@ nextflow_process { } test("homo_sapiens - [bam, bam] region - panel") { - tag "test" when { process { """ @@ -301,7 +300,6 @@ nextflow_process { } test("homo_sapiens - [bam, bam] region sample rename - panel") { - tag "test" when { process { """ diff --git a/modules/nf-core/glimpse2/phase/tests/nextflow.config b/modules/nf-core/glimpse2/phase/tests/nextflow.config index 310c7f220dd7..8710a5688bf7 100644 --- a/modules/nf-core/glimpse2/phase/tests/nextflow.config +++ b/modules/nf-core/glimpse2/phase/tests/nextflow.config @@ -1,11 +1,11 @@ process { withName: GLIMPSE2_PHASE { - cpus = 1 - ext.args = "--seed 1" + cpus = 1 // needed for deterministic output + ext.args = "--seed 1" ext.suffix = "vcf" } withName: SAMTOOLS_VIEW { - ext.args = "--output-fmt cram" + ext.args = "--output-fmt cram" ext.args2 = "embed-ref=2" } } diff --git a/modules/nf-core/glimpse2/splitreference/main.nf b/modules/nf-core/glimpse2/splitreference/main.nf index 0311e09dabc2..84ec88721566 100644 --- a/modules/nf-core/glimpse2/splitreference/main.nf +++ b/modules/nf-core/glimpse2/splitreference/main.nf @@ -1,8 +1,8 @@ process GLIMPSE2_SPLITREFERENCE { - tag "$meta.id" + tag "${meta.id}" label 'process_low' - beforeScript """ + beforeScript """ if cat /proc/cpuinfo | grep avx2 -q then echo "Feature AVX2 present" @@ -13,34 +13,33 @@ process GLIMPSE2_SPLITREFERENCE { """ conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/glimpse-bio:2.0.1--h46b9e50_1': - 'biocontainers/glimpse-bio:2.0.1--h46b9e50_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/glimpse-bio:2.0.1--h46b9e50_1' + : 'biocontainers/glimpse-bio:2.0.1--h46b9e50_1'}" input: - tuple val(meta) , path(reference), path(reference_index), val(input_region), val(output_region), path(map) - + tuple val(meta), path(reference), path(reference_index), val(input_region), val(output_region), path(map) output: - tuple val(meta), path("*.bin"), emit: bin_ref - path "versions.yml" , emit: versions + tuple val(meta), path("*.bin"), emit: bin_ref + path "versions.yml" , emit: versions when: - task.ext.when == null || task.ext.when + task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}_${output_region.replace(":","_")}" - def map_command = map ? "--map $map" : "" + def prefix = task.ext.prefix ?: "${meta.id}_${output_region.replace(":", "_")}" + def map_command = map ? "--map ${map}" : "" """ GLIMPSE2_split_reference \\ - $args \\ - --reference $reference \\ - $map_command \\ - --input-region $input_region \\ - --output-region $output_region \\ - --thread $task.cpus \\ + ${args} \\ + --reference ${reference} \\ + ${map_command} \\ + --input-region ${input_region} \\ + --output-region ${output_region} \\ + --thread ${task.cpus} \\ --output ${prefix} cat <<-END_VERSIONS > versions.yml @@ -50,7 +49,7 @@ process GLIMPSE2_SPLITREFERENCE { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}_${output_region.replace(":","_")}" + def prefix = task.ext.prefix ?: "${meta.id}_${output_region.replace(":", "_")}" """ touch ${prefix}.bin diff --git a/modules/nf-core/glimpse2/splitreference/tests/nextflow.config b/modules/nf-core/glimpse2/splitreference/tests/nextflow.config index 5dc286695cc9..5f347b20d3a4 100644 --- a/modules/nf-core/glimpse2/splitreference/tests/nextflow.config +++ b/modules/nf-core/glimpse2/splitreference/tests/nextflow.config @@ -1,8 +1,8 @@ process { withName: GLIMPSE2_SPLITREFERENCE { - ext.args = [ + ext.args = [ "--sparse-maf 0.01", - "--keep-monomorphic-ref-sites" + "--keep-monomorphic-ref-sites", ].join(' ') ext.prefix = { "${meta.id}" } } diff --git a/modules/nf-core/minimac4/compressref/main.nf b/modules/nf-core/minimac4/compressref/main.nf index 8a69ab4d40e4..cb1483b4d32e 100644 --- a/modules/nf-core/minimac4/compressref/main.nf +++ b/modules/nf-core/minimac4/compressref/main.nf @@ -1,11 +1,11 @@ process MINIMAC4_COMPRESSREF { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/minimac4:4.1.6--hcb620b3_1': - 'biocontainers/minimac4:4.1.6--hcb620b3_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/minimac4:4.1.6--hcb620b3_1' + : 'biocontainers/minimac4:4.1.6--hcb620b3_1'}" input: tuple val(meta), path(ref), path(ref_index) // Reference index is autodetected from reference file name @@ -22,9 +22,9 @@ process MINIMAC4_COMPRESSREF { def prefix = task.ext.prefix ?: "${meta.id}" """ minimac4 \\ - --compress-reference $ref\\ - $args \\ - --threads $task.cpus \\ + --compress-reference ${ref}\\ + ${args} \\ + --threads ${task.cpus} \\ -o ${prefix}.msav cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/minimac4/impute/main.nf b/modules/nf-core/minimac4/impute/main.nf index c26454cc4dab..8b2af40f2adb 100644 --- a/modules/nf-core/minimac4/impute/main.nf +++ b/modules/nf-core/minimac4/impute/main.nf @@ -1,11 +1,11 @@ process MINIMAC4_IMPUTE { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/minimac4:4.1.6--hcb620b3_1': - 'biocontainers/minimac4:4.1.6--hcb620b3_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/minimac4:4.1.6--hcb620b3_1' + : 'biocontainers/minimac4:4.1.6--hcb620b3_1'}" input: tuple val(meta), path(target_vcf), path(target_index), path(ref_msav), path(sites_vcf), path(sites_index), path(map), val(region) @@ -32,13 +32,13 @@ process MINIMAC4_IMPUTE { def region_cmd = region ? "--region $region" : "" """ minimac4 \\ - $ref_msav \\ - $target_vcf \\ - $args \\ - $sites_cmd \\ - $map_cmd \\ - $region_cmd \\ - --threads $task.cpus \\ + ${ref_msav} \\ + ${target_vcf} \\ + ${args} \\ + ${sites_cmd} \\ + ${map_cmd} \\ + ${region_cmd} \\ + --threads ${task.cpus} \\ -o ${prefix}.${extension} cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/minimac4/impute/tests/nextflow.config b/modules/nf-core/minimac4/impute/tests/nextflow.config index 79d5afd87e05..ec1172342b26 100644 --- a/modules/nf-core/minimac4/impute/tests/nextflow.config +++ b/modules/nf-core/minimac4/impute/tests/nextflow.config @@ -1,5 +1,5 @@ process { - withName: 'MINIMAC4_IMPUTE' { - ext.args = {"${params.minimac4_args}"} + withName: MINIMAC4_IMPUTE { + ext.args = { "${params.minimac4_args}" } } } diff --git a/modules/nf-core/quilt/quilt/main.nf b/modules/nf-core/quilt/quilt/main.nf index 3003ce3c12d6..2054f824fe16 100644 --- a/modules/nf-core/quilt/quilt/main.nf +++ b/modules/nf-core/quilt/quilt/main.nf @@ -1,70 +1,75 @@ process QUILT_QUILT { - tag "$meta.id" + 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:1.0.5--r43h06b5641_0': - 'biocontainers/r-quilt:1.0.5--r43h06b5641_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/r-quilt:1.0.5--r43h06b5641_0' + : 'biocontainers/r-quilt:1.0.5--r43h06b5641_0'}" input: tuple val(meta), path(bams), path(bais), path(bamlist), path(samplename), path(reference_haplotype_file), path(reference_legend_file), 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 - path "versions.yml", emit: versions + 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 + path "versions.yml" , emit: versions 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 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" : "" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def suffix = task.ext.suffix ?: "vcf.gz" - if (!(args ==~ /.*--seed.*/)) {args += " --seed=1"} + 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 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" ] ; + if [ -n "${bamlist}" ] ; then - BAM_LIST="$bamlist" + BAM_LIST="${bamlist}" else - printf "%s\\n" $bams | tr -d '[],' > all_files.txt + printf "%s\\n" ${bams} | tr -d '[],' > all_files.txt BAM_LIST="all_files.txt" fi QUILT.R \\ ${list_command}\$BAM_LIST \\ - $genetic_map_command \\ - $posfile_command \\ - $phasefile_command \\ - $samplename_command \\ - --chr=$chr \\ - $start_command \\ - $end_command \\ - $buffer_command \\ - --nGen=$ngen \\ - --nCores=$task.cpus \\ + ${genetic_map_command} \\ + ${posfile_command} \\ + ${phasefile_command} \\ + ${samplename_command} \\ + --chr=${chr} \\ + ${start_command} \\ + ${end_command} \\ + ${buffer_command} \\ + --nGen=${ngen} \\ + --nCores=${task.cpus} \\ --outputdir="." \\ - --reference_haplotype_file=$reference_haplotype_file \\ - --reference_legend_file=$reference_legend_file \\ + --reference_haplotype_file=${reference_haplotype_file} \\ + --reference_legend_file=${reference_legend_file} \\ --output_filename=${prefix}.${suffix} \\ - $args + ${args} cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/quilt/quilt/tests/nextflow.config b/modules/nf-core/quilt/quilt/tests/nextflow.config index 55300fd5d60a..bee66cb5174c 100644 --- a/modules/nf-core/quilt/quilt/tests/nextflow.config +++ b/modules/nf-core/quilt/quilt/tests/nextflow.config @@ -4,13 +4,13 @@ process { cpus: 1 ] withName: QUILT_QUILT { - ext.args = {"${params.quilt_args}"} + ext.args = { "${params.quilt_args}" } } withName: BCFTOOLS_QUERY { - ext.args = {"${params.bcftools_query_args}"} - ext.suffix = {"${params.bcftools_query_suffix}"} + ext.args = { "${params.bcftools_query_args}" } + ext.suffix = { "${params.bcftools_query_suffix}" } } withName: GAWK_NAME { - ext.suffix = {"${params.gawk_name_suffix}"} + ext.suffix = { "${params.gawk_name_suffix}" } } } diff --git a/modules/nf-core/shapeit5/ligate/main.nf b/modules/nf-core/shapeit5/ligate/main.nf index 66c13225f207..9522d8bf1c9a 100644 --- a/modules/nf-core/shapeit5/ligate/main.nf +++ b/modules/nf-core/shapeit5/ligate/main.nf @@ -1,11 +1,11 @@ process SHAPEIT5_LIGATE { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/shapeit5:5.1.1--hb60d31d_0': - 'biocontainers/shapeit5:5.1.1--hb60d31d_0'}" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/shapeit5:5.1.1--hb60d31d_0' + : 'biocontainers/shapeit5:5.1.1--hb60d31d_0'}" input: tuple val(meta), path(input_list), path(input_list_index) @@ -22,12 +22,12 @@ process SHAPEIT5_LIGATE { def prefix = task.ext.prefix ?: "${meta.id}" def suffix = task.ext.suffix ?: "vcf.gz" """ - printf "%s\\n" $input_list | tr -d '[],' | sort -V > all_files.txt + printf "%s\\n" ${input_list} | tr -d '[],' | sort -V > all_files.txt SHAPEIT5_ligate \\ - $args \\ + ${args} \\ --input all_files.txt \\ - --thread $task.cpus \\ + --thread ${task.cpus} \\ --output ${prefix}.${suffix} cat <<-END_VERSIONS > versions.yml @@ -37,8 +37,9 @@ process SHAPEIT5_LIGATE { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" - def suffix = task.ext.suffix ?: "vcf.gz" + def prefix = task.ext.prefix ?: "${meta.id}" + def suffix = task.ext.suffix ?: "vcf.gz" + def create_cmd = suffix.endsWith(".gz") ? "echo '' | gzip >" : "touch" """ ${create_cmd} ${prefix}.${suffix} diff --git a/modules/nf-core/shapeit5/ligate/tests/nextflow.config b/modules/nf-core/shapeit5/ligate/tests/nextflow.config index c72ccf4ef3a0..3e65f4848b50 100644 --- a/modules/nf-core/shapeit5/ligate/tests/nextflow.config +++ b/modules/nf-core/shapeit5/ligate/tests/nextflow.config @@ -1,5 +1,5 @@ process { - withName: "BCFTOOLS_VIEW" { + withName: BCFTOOLS_VIEW { ext.args = { "--regions ${meta.region} -Ob --write-index=csi -e 'GT=\"./.\"||GT=\".\"'" } ext.prefix = { "${meta.id}_${meta.region}" } } diff --git a/modules/nf-core/shapeit5/phasecommon/main.nf b/modules/nf-core/shapeit5/phasecommon/main.nf index df22b868617f..e21117750d4b 100644 --- a/modules/nf-core/shapeit5/phasecommon/main.nf +++ b/modules/nf-core/shapeit5/phasecommon/main.nf @@ -1,24 +1,24 @@ process SHAPEIT5_PHASECOMMON { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/shapeit5:5.1.1--hb60d31d_0': - 'biocontainers/shapeit5:5.1.1--hb60d31d_0'}" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/shapeit5:5.1.1--hb60d31d_0' + : 'biocontainers/shapeit5:5.1.1--hb60d31d_0'}" input: - tuple val(meta), path(input), path(input_index), path(pedigree), val(region), path(reference), path(reference_index), path(scaffold), path(scaffold_index), path(map) + tuple val(meta), path(input), path(input_index), path(pedigree), val(region), path(reference), path(reference_index), path(scaffold), path(scaffold_index), path(map) output: - tuple val(meta), path("*.{bcf,graph,bh}"), emit: phased_variant - path "versions.yml" , emit: versions + tuple val(meta), path("*.{bcf,graph,bh}"), emit: phased_variant + path "versions.yml" , emit: versions when: - task.ext.when == null || task.ext.when + task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" def extension = args.contains("--output-format bcf") ? "bcf" : @@ -26,23 +26,25 @@ process SHAPEIT5_PHASECOMMON { args.contains("--output-format bh") ? "bh" : "bcf" - if ("$input" == "${prefix}.${extension}") error "Input and output names are the same, set prefix in module configuration to disambiguate!" + if ("${input}" == "${prefix}.${extension}") { + error("Input and output names are the same, set prefix in module configuration to disambiguate!") + } - def map_command = map ? "--map $map" : "" - def reference_command = reference ? "--reference $reference" : "" - def scaffold_command = scaffold ? "--scaffold $scaffold" : "" - def pedigree_command = pedigree ? "--pedigree $pedigree" : "" + def map_command = map ? "--map ${map}" : "" + def reference_command = reference ? "--reference ${reference}" : "" + def scaffold_command = scaffold ? "--scaffold ${scaffold}" : "" + def pedigree_command = pedigree ? "--pedigree ${pedigree}" : "" """ SHAPEIT5_phase_common \\ - $args \\ - --input $input \\ - $map_command \\ - $reference_command \\ - $scaffold_command \\ - $pedigree_command \\ - --region $region \\ - --thread $task.cpus \\ + ${args} \\ + --input ${input} \\ + ${map_command} \\ + ${reference_command} \\ + ${scaffold_command} \\ + ${pedigree_command} \\ + --region ${region} \\ + --thread ${task.cpus} \\ --output ${prefix}.${extension} cat <<-END_VERSIONS > versions.yml @@ -52,8 +54,9 @@ process SHAPEIT5_PHASECOMMON { """ stub: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def extension = args.contains("--output-format bcf") ? "bcf" : args.contains("--output-format graph") ? "graph" : args.contains("--output-format bh") ? "bh" : diff --git a/modules/nf-core/shapeit5/phasecommon/tests/nextflow.config b/modules/nf-core/shapeit5/phasecommon/tests/nextflow.config index 28775613ce50..6d3b72fcc140 100644 --- a/modules/nf-core/shapeit5/phasecommon/tests/nextflow.config +++ b/modules/nf-core/shapeit5/phasecommon/tests/nextflow.config @@ -1,6 +1,6 @@ process { withName: SHAPEIT5_PHASECOMMON { - cpus = 1 // needed for deterministic output + cpus = 1 // needed for deterministic output ext.args = params.shapeit5_phasecommon_args } } diff --git a/modules/nf-core/shapeit5/phaserare/main.nf b/modules/nf-core/shapeit5/phaserare/main.nf index 313d5be475b7..01a5238e4462 100644 --- a/modules/nf-core/shapeit5/phaserare/main.nf +++ b/modules/nf-core/shapeit5/phaserare/main.nf @@ -1,8 +1,8 @@ process SHAPEIT5_PHASERARE { - tag "$meta.id" + tag "${meta.id}" label 'process_low' - beforeScript """ + beforeScript """ if cat /proc/cpuinfo | grep avx2 -q then echo "Feature AVX2 present on host" @@ -13,12 +13,12 @@ process SHAPEIT5_PHASERARE { """ conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/shapeit5:5.1.1--hb60d31d_0': - 'biocontainers/shapeit5:5.1.1--hb60d31d_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/shapeit5:5.1.1--hb60d31d_0' + : 'biocontainers/shapeit5:5.1.1--hb60d31d_0'}" input: - tuple val(meta), path(input), path(input_index), path(pedigree), val(input_region), path(scaffold), path(scaffold_index), val(scaffold_region), path(map) + tuple val(meta), path(input), path(input_index), path(pedigree), val(input_region), path(scaffold), path(scaffold_index), val(scaffold_region), path(map) output: tuple val(meta), path("*.{vcf,bcf,vcf.gz,bcf.gz}"), emit: phased_variant @@ -28,26 +28,30 @@ process SHAPEIT5_PHASERARE { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" def suffix = task.ext.suffix ?: "vcf.gz" - if ("$input" == "${prefix}.${suffix}") error "Input and output names are the same, set prefix in module configuration to disambiguate!" - if ("$scaffold" == "${prefix}.${suffix}") error "Scaffold and output names are the same, set prefix in module configuration to disambiguate!" + if ("${input}" == "${prefix}.${suffix}") { + error("Input and output names are the same, set prefix in module configuration to disambiguate!") + } + if ("${scaffold}" == "${prefix}.${suffix}") { + error("Scaffold and output names are the same, set prefix in module configuration to disambiguate!") + } - def map_command = map ? "--map $map" : "" - def pedigree_command = pedigree ? "--pedigree $pedigree" : "" + def map_command = map ? "--map ${map}" : "" + def pedigree_command = pedigree ? "--pedigree ${pedigree}" : "" """ SHAPEIT5_phase_rare \\ - $args \\ - --input $input \\ - --scaffold $scaffold \\ - $map_command \\ - $pedigree_command \\ - --input-region $input_region \\ - --scaffold-region $scaffold_region \\ - --thread $task.cpus \\ + ${args} \\ + --input ${input} \\ + --scaffold ${scaffold} \\ + ${map_command} \\ + ${pedigree_command} \\ + --input-region ${input_region} \\ + --scaffold-region ${scaffold_region} \\ + --thread ${task.cpus} \\ --output ${prefix}.${suffix} cat <<-END_VERSIONS > versions.yml @@ -59,6 +63,7 @@ process SHAPEIT5_PHASERARE { stub: def prefix = task.ext.prefix ?: "${meta.id}" def suffix = task.ext.suffix ?: "vcf.gz" + def create_cmd = suffix.endsWith(".gz") ? "echo '' | gzip >" : "touch" """ ${create_cmd} ${prefix}.${suffix} diff --git a/modules/nf-core/shapeit5/phaserare/tests/nextflow.config b/modules/nf-core/shapeit5/phaserare/tests/nextflow.config index 9e5e8dbe4115..cf1799b552a2 100644 --- a/modules/nf-core/shapeit5/phaserare/tests/nextflow.config +++ b/modules/nf-core/shapeit5/phaserare/tests/nextflow.config @@ -1,11 +1,11 @@ process { withName: SHAPEIT5_PHASECOMMON { - cpus = 1 // Needed for deterministic output + cpus = 1 // needed for deterministic output ext.args = params.shapeit5_phasecommon_args } withName: SHAPEIT5_PHASERARE { - cpus = 1 // Needed for deterministic output + cpus = 1 // needed for deterministic output ext.args = params.shapeit5_phaserare_args } } diff --git a/modules/nf-core/shapeit5/switch/main.nf b/modules/nf-core/shapeit5/switch/main.nf index 2c26271a9e7a..20dc271551c5 100644 --- a/modules/nf-core/shapeit5/switch/main.nf +++ b/modules/nf-core/shapeit5/switch/main.nf @@ -1,37 +1,38 @@ process SHAPEIT5_SWITCH { - tag "$meta.id" + tag "${meta.id}" label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/shapeit5:5.1.1--hb60d31d_0': - 'biocontainers/shapeit5:5.1.1--hb60d31d_0'}" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/shapeit5:5.1.1--hb60d31d_0' + : 'biocontainers/shapeit5:5.1.1--hb60d31d_0'}" input: - tuple val(meta), path(estimate), path(estimate_index), val(region), path(pedigree), path(truth), path(truth_index), path(freq) , path(freq_index) + tuple val(meta), path(estimate), path(estimate_index), val(region), path(pedigree), path(truth), path(truth_index), path(freq), path(freq_index) output: tuple val(meta), path("*.txt.gz"), emit: errors path "versions.yml" , emit: versions when: - task.ext.when == null || task.ext.when + task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def freq_cmd = freq ? "--frequency ${freq}" : "" - def pedigree_cmd = pedigree ? "--pedigree ${pedigree}": "" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + def freq_cmd = freq ? "--frequency ${freq}" : "" + def pedigree_cmd = pedigree ? "--pedigree ${pedigree}" : "" """ SHAPEIT5_switch \\ - $args \\ - --estimation $estimate \\ - --region $region \\ - --validation $truth \\ - $freq_cmd \\ - $pedigree_cmd \\ - --thread $task.cpus \\ + ${args} \\ + --estimation ${estimate} \\ + --region ${region} \\ + --validation ${truth} \\ + ${freq_cmd} \\ + ${pedigree_cmd} \\ + --thread ${task.cpus} \\ --output ${prefix} cat <<-END_VERSIONS > versions.yml @@ -41,8 +42,9 @@ process SHAPEIT5_SWITCH { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" - def create_cmd = "echo '' | gzip >" + def prefix = task.ext.prefix ?: "${meta.id}" + + def create_cmd = "echo '' | gzip >" """ ${create_cmd} ${prefix}.block.switch.txt.gz ${create_cmd} ${prefix}.calibration.switch.txt.gz diff --git a/modules/nf-core/shapeit5/switch/tests/nextflow.config b/modules/nf-core/shapeit5/switch/tests/nextflow.config index 28775613ce50..6d3b72fcc140 100644 --- a/modules/nf-core/shapeit5/switch/tests/nextflow.config +++ b/modules/nf-core/shapeit5/switch/tests/nextflow.config @@ -1,6 +1,6 @@ process { withName: SHAPEIT5_PHASECOMMON { - cpus = 1 // needed for deterministic output + cpus = 1 // needed for deterministic output ext.args = params.shapeit5_phasecommon_args } } diff --git a/modules/nf-core/stitch/main.nf b/modules/nf-core/stitch/main.nf index d76f10ecd836..4a213fa1c1a2 100644 --- a/modules/nf-core/stitch/main.nf +++ b/modules/nf-core/stitch/main.nf @@ -1,16 +1,16 @@ process STITCH { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/r-stitch:1.7.3--r44h64f727c_0': - 'biocontainers/r-stitch:1.7.3--r44h64f727c_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/r-stitch:1.7.3--r44h64f727c_0' + : 'biocontainers/r-stitch:1.7.3--r44h64f727c_0'}" input: tuple val(meta), path(collected_crams), path(collected_crais), path(cramlist), path(samplename), path(posfile), path(input, stageAs: "input"), path(genetic_map), path(rdata, stageAs: "RData_in"), val(chromosome_name), val(start), val(end), val(K), val(nGen) tuple val(meta2), path(fasta), path(fasta_fai) - val(seed) + val seed output: tuple val(meta), path("input", type: "dir") , emit: input @@ -24,19 +24,19 @@ process STITCH { task.ext.when == null || task.ext.when script: - def prefix = task.ext.prefix ?: "${meta.id}" - def args = task.ext.args ?: "" - def args2 = task.ext.args2 ?: "" + def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: "" + def args2 = task.ext.args2 ?: "" - generate_input_only = args2.contains( "--generateInputOnly TRUE" ) - bgen_output = args2.contains( "--output_format bgen" ) - def suffix = bgen_output ? "bgen" : "vcf.gz" + generate_input_only = args2.contains("--generateInputOnly TRUE") + bgen_output = args2.contains("--output_format bgen") + def suffix = bgen_output ? "bgen" : "vcf.gz" def crams_list = collected_crams instanceof Collection ? collected_crams : [collected_crams] - def reads_ext = crams_list ? crams_list.collect {path -> path.extension }.unique() : [] + def reads_ext = crams_list ? crams_list.collect { path -> path.extension }.unique() : [] - if ( reads_ext.size() > 1 ) { - error "STITCH process: Mixed input read file types detected: ${reads_ext}. Please provide either all BAM or all CRAM files." + if (reads_ext.size() > 1) { + error("STITCH process: Mixed input read file types detected: ${reads_ext}. Please provide either all BAM or all CRAM files.") } def cramlist_cmd = cramlist && reads_ext == ["cram"] ? "--cramlist ${cramlist}" : "" def bamlist_cmd = cramlist && reads_ext == ["bam" ] ? "--bamlist ${cramlist}" : "" @@ -79,18 +79,20 @@ process STITCH { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" - def _args = task.ext.args ?: "" - def args2 = task.ext.args2 ?: "" - def nb_samples = collected_crams.size() - generate_input_only = args2.contains( "--generateInputOnly TRUE" ) - bgen_output = args2.contains( "--output_format bgen" ) - def generate_plots_cmd = !generate_input_only - def generate_file_cmd = !generate_input_only ? bgen_output ? "touch ${prefix}.bgen" : "echo '' | gzip > ${prefix}.vcf.gz" : "" - def rsync_version_cmd = rdata ? "rsync: \$(rsync --version | head -n1 | sed 's/^rsync version //; s/ .*\$//')" : "" + def prefix = task.ext.prefix ?: "${meta.id}" + def _args = task.ext.args ?: "" + def args2 = task.ext.args2 ?: "" + + def nb_samples = collected_crams.size() + generate_input_only = args2.contains("--generateInputOnly TRUE") + bgen_output = args2.contains("--output_format bgen") + + def generate_plots_cmd = !generate_input_only + def generate_file_cmd = !generate_input_only ? bgen_output ? "touch ${prefix}.bgen" : "echo '' | gzip > ${prefix}.vcf.gz" : "" + def rsync_version_cmd = rdata ? "rsync: \$(rsync --version | head -n1 | sed 's/^rsync version //; s/ .*\$//')" : "" """ mkdir -p input - for i in {1..$nb_samples} + for i in {1..${nb_samples}} do touch "input/sample.\$i.input.${chromosome_name}.RData" done diff --git a/modules/nf-core/stitch/tests/main.nf.test b/modules/nf-core/stitch/tests/main.nf.test index 24df439f24fd..0581221502a3 100644 --- a/modules/nf-core/stitch/tests/main.nf.test +++ b/modules/nf-core/stitch/tests/main.nf.test @@ -90,8 +90,8 @@ nextflow_process { meta, file(vcf).name, path(vcf).vcf.header.getGenotypeSamples().sort(), - path(vcf).vcf.summary, - path(vcf).vcf.variantsMD5 + path(vcf).vcf.summary + // path(vcf).vcf.variantsMD5 // Not reproducible without seed ]}, process.out.versions ).match() } diff --git a/modules/nf-core/stitch/tests/main.nf.test.snap b/modules/nf-core/stitch/tests/main.nf.test.snap index f6039ee0dd09..65fd19531aad 100644 --- a/modules/nf-core/stitch/tests/main.nf.test.snap +++ b/modules/nf-core/stitch/tests/main.nf.test.snap @@ -91,8 +91,7 @@ "normal", "tumour" ], - "VcfFile [chromosomes=[chr21], sampleCount=2, variantCount=10, phased=false, phasedAutodetect=false]", - "e41c51d08be2cdacd81fc8800cffb156" + "VcfFile [chromosomes=[chr21], sampleCount=2, variantCount=10, phased=false, phasedAutodetect=false]" ] ], [ diff --git a/modules/nf-core/stitch/tests/nextflow.config b/modules/nf-core/stitch/tests/nextflow.config index 4c593d71f968..c87ae2a0cf15 100644 --- a/modules/nf-core/stitch/tests/nextflow.config +++ b/modules/nf-core/stitch/tests/nextflow.config @@ -1,8 +1,8 @@ process { withName: STITCH { - ext.args2 = {"${params.stitch_args2}"} ?: "" + ext.args2 = { "${params.stitch_args2}" } ?: "" } withName: STITCH_GENERATE_INPUTS { - ext.args2 = {"${params.stitch_args2}"} ?: "" + ext.args2 = { "${params.stitch_args2}" } ?: "" } } diff --git a/subworkflows/nf-core/bam_impute_quilt/main.nf b/subworkflows/nf-core/bam_impute_quilt/main.nf index ffae2fe7fcc7..6a1e35971f5d 100644 --- a/subworkflows/nf-core/bam_impute_quilt/main.nf +++ b/subworkflows/nf-core/bam_impute_quilt/main.nf @@ -3,20 +3,19 @@ include { GLIMPSE2_LIGATE } from '../../../modules/nf-core/glimpse2/ligate' include { BCFTOOLS_INDEX } from '../../../modules/nf-core/bcftools/index' workflow BAM_IMPUTE_QUILT { - take: - ch_input // channel (mandatory): [ [id], [bam], [bai], bampaths, bamnames ] - ch_hap_legend // channel (mandatory): [ [panel, chr], hap, legend ] - ch_posfile // channel (mandatory): [ [panel, chr], posfile ] - ch_chunks // channel (optional) : [ [panel, chr], chr, start, end ] - ch_map // channel (optional) : [ [panel, chr], map ] - ch_fasta // channel (optional) : [ [genome], fa, fai ] - n_gen // integer: Number of generations since founding or mixing - buffer // integer: Buffer of region to perform imputation over + ch_input // channel (mandatory): [ [id], [bam], [bai], bampaths, bamnames ] + ch_hap_legend // channel (mandatory): [ [panel, chr], hap, legend ] + ch_posfile // channel (mandatory): [ [panel, chr], posfile ] + ch_chunks // channel (optional) : [ [panel, chr], chr, start, end ] + ch_map // channel (optional) : [ [panel, chr], map ] + ch_fasta // channel (optional) : [ [genome], fa, fai ] + n_gen // integer: Number of generations since founding or mixing + buffer // integer: Buffer of region to perform imputation over main: - ch_versions = channel.empty() + ch_versions = channel.empty() // Make final channel with parameters ch_parameters = ch_hap_legend @@ -24,14 +23,13 @@ workflow BAM_IMPUTE_QUILT { .combine(ch_map, by: 0) .combine(ch_chunks, by: 0) - ch_parameters.ifEmpty{ - error "ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input." + ch_parameters.ifEmpty { + error("ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input.") } ch_bam_params = ch_input .combine(ch_parameters) - .map{ - metaI, bam, bai, bampath, bamname, metaPC, hap, legend, posfile, gmap, chr, start, end -> + .map { metaI, bam, bai, bampath, bamname, metaPC, hap, legend, posfile, gmap, chr, start, end -> def regionout = "${chr}" if (start != [] && end != []) { regionout = "${chr}:${start}-${end}" @@ -45,33 +43,32 @@ workflow BAM_IMPUTE_QUILT { ] } - QUILT_QUILT( ch_bam_params, ch_fasta ) - ch_versions = ch_versions.mix( QUILT_QUILT.out.versions.first() ) + QUILT_QUILT(ch_bam_params, ch_fasta) + ch_versions = ch_versions.mix(QUILT_QUILT.out.versions.first()) // Ligate all phased files in one and index it ligate_input = QUILT_QUILT.out.vcf - .join( QUILT_QUILT.out.tbi ) - .map{ meta, vcf, index -> + .join(QUILT_QUILT.out.tbi) + .map { meta, vcf, index -> def keysToKeep = meta.keySet() - ['regionout'] - [ meta.subMap(keysToKeep), vcf, index ] + [meta.subMap(keysToKeep), vcf, index] } .groupTuple() - GLIMPSE2_LIGATE( ligate_input ) - ch_versions = ch_versions.mix( GLIMPSE2_LIGATE.out.versions.first() ) + GLIMPSE2_LIGATE(ligate_input) + ch_versions = ch_versions.mix(GLIMPSE2_LIGATE.out.versions.first()) - BCFTOOLS_INDEX( GLIMPSE2_LIGATE.out.merged_variants ) - ch_versions = ch_versions.mix( BCFTOOLS_INDEX.out.versions.first() ) + BCFTOOLS_INDEX(GLIMPSE2_LIGATE.out.merged_variants) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX.out.versions.first()) // Join imputed and index files - ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants - .join( - BCFTOOLS_INDEX.out.tbi - .mix(BCFTOOLS_INDEX.out.csi) - ) + ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants.join( + BCFTOOLS_INDEX.out.tbi.mix(BCFTOOLS_INDEX.out.csi), + failOnMismatch: true, + failOnDuplicate: true, + ) emit: - vcf_index = ch_vcf_index // channel: [ [id, chr], vcf, tbi ] - versions = ch_versions // channel: [ versions.yml ] - + vcf_index = ch_vcf_index // channel: [ [id, chr], vcf, tbi ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/bam_impute_quilt/tests/nextflow.config b/subworkflows/nf-core/bam_impute_quilt/tests/nextflow.config index 628ea54b1e8b..7ab7994735f9 100644 --- a/subworkflows/nf-core/bam_impute_quilt/tests/nextflow.config +++ b/subworkflows/nf-core/bam_impute_quilt/tests/nextflow.config @@ -1,9 +1,9 @@ process { withName: QUILT_QUILT { - cpus = 1 // Needed to have deterministic output for testing + cpus = 1 // needed for deterministic output ext.args = { "${params.quilt_args}" } ext.prefix = { "${meta.id}_${meta.chr}_${meta.regionout}.quilt" } - tag = { "${meta.id} ${meta.chr} ${meta.regionout}" } + tag = { "${meta.id} ${meta.chr} ${meta.regionout}" } } withName: GLIMPSE2_LIGATE { @@ -13,7 +13,7 @@ process { withName: BCFTOOLS_INDEX { ext.args = '--csi' - tag = { "${meta.id} ${meta.chr}" } + tag = { "${meta.id} ${meta.chr}" } publishDir = [enabled: false] } } diff --git a/subworkflows/nf-core/bam_impute_stitch/main.nf b/subworkflows/nf-core/bam_impute_stitch/main.nf index 2dc7843991c4..bcae1b9840d9 100644 --- a/subworkflows/nf-core/bam_impute_stitch/main.nf +++ b/subworkflows/nf-core/bam_impute_stitch/main.nf @@ -1,39 +1,37 @@ -include { STITCH } from '../../../modules/nf-core/stitch/main' -include { GLIMPSE2_LIGATE } from '../../../modules/nf-core/glimpse2/ligate/main' -include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_1 } from '../../../modules/nf-core/bcftools/index/main' -include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_2 } from '../../../modules/nf-core/bcftools/index/main' +include { STITCH } from '../../../modules/nf-core/stitch/main' +include { GLIMPSE2_LIGATE } from '../../../modules/nf-core/glimpse2/ligate/main' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_PHASE } from '../../../modules/nf-core/bcftools/index/main' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_LIGATE } from '../../../modules/nf-core/bcftools/index/main' workflow BAM_IMPUTE_STITCH { - take: - ch_input // channel (mandatory): [ [id], [bam], [bai], bampaths, bamnames ] - ch_posfile // channel (mandatory): [ [panel, chr], posfile ] - ch_chunks // channel (optional) : [ [panel, chr], chr, start, end ] - ch_map // channel (optional) : [ [panel, chr], map ] - ch_fasta // channel (optional) : [ [genome], fa, fai ] - k_val // integer: k value for STITCH - n_gen // integer: number of generations for STITCH - seed // value : seed for random number generator + ch_input // channel (mandatory): [ [id], [bam], [bai], bampaths, bamnames ] + ch_posfile // channel (mandatory): [ [panel, chr], posfile ] + ch_chunks // channel (optional) : [ [panel, chr], chr, start, end ] + ch_map // channel (optional) : [ [panel, chr], map ] + ch_fasta // channel (optional) : [ [genome], fa, fai ] + k_val // integer: k value for STITCH + n_gen // integer: number of generations for STITCH + seed // value : seed for random number generator main: - ch_versions = channel.empty() + ch_versions = channel.empty() // Make final channel with parameters ch_parameters = ch_posfile .combine(ch_map, by: 0) .combine(ch_chunks, by: 0) - ch_parameters.ifEmpty{ - error "ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input." + ch_parameters.ifEmpty { + error("ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input.") } ch_bam_params = ch_input .combine(ch_parameters) - .map{ - metaI, bam, bai, bampath, bamname, metaPC, posfile, gmap, chr, start, end -> + .map { metaI, bam, bai, bampath, bamname, metaPC, posfile, gmap, chr, start, end -> if (!chr) { - error "ERROR: chromosome is not provided in ch_chunks." + error("ERROR: chromosome is not provided in ch_chunks.") } def regionout = "${chr}" if (start != [] && end != []) { @@ -41,43 +39,48 @@ workflow BAM_IMPUTE_STITCH { } [ metaPC + metaI + ["regionout": regionout], - bam, bai, bampath, bamname, posfile, [], gmap, [], chr, start, end, k_val, n_gen + bam, bai, bampath, bamname, + posfile, [], + gmap, [], + chr, start, end, + k_val, n_gen ] } - STITCH( ch_bam_params, ch_fasta, seed ) + STITCH(ch_bam_params, ch_fasta, seed) ch_versions = ch_versions.mix(STITCH.out.versions.first()) // Index imputed annotated VCF - BCFTOOLS_INDEX_1(STITCH.out.vcf) - ch_versions = ch_versions.mix(BCFTOOLS_INDEX_1.out.versions.first()) + BCFTOOLS_INDEX_PHASE(STITCH.out.vcf) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_PHASE.out.versions.first()) // Ligate all phased files in one and index it ligate_input = STITCH.out.vcf - .join( BCFTOOLS_INDEX_1.out.tbi - .mix(BCFTOOLS_INDEX_1.out.csi) + .join( + BCFTOOLS_INDEX_PHASE.out.tbi.mix(BCFTOOLS_INDEX_PHASE.out.csi), + failOnMismatch: true, + failOnDuplicate: true, ) - .map{ meta, vcf, index -> + .map { meta, vcf, index -> def keysToKeep = meta.keySet() - ['regionout'] - [ meta.subMap(keysToKeep), vcf, index ] + [meta.subMap(keysToKeep), vcf, index] } .groupTuple() - GLIMPSE2_LIGATE( ligate_input ) - ch_versions = ch_versions.mix( GLIMPSE2_LIGATE.out.versions.first() ) + GLIMPSE2_LIGATE(ligate_input) + ch_versions = ch_versions.mix(GLIMPSE2_LIGATE.out.versions.first()) - BCFTOOLS_INDEX_2( GLIMPSE2_LIGATE.out.merged_variants ) - ch_versions = ch_versions.mix( BCFTOOLS_INDEX_2.out.versions.first() ) + BCFTOOLS_INDEX_LIGATE(GLIMPSE2_LIGATE.out.merged_variants) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_LIGATE.out.versions.first()) // Join imputed and index files - ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants - .join( - BCFTOOLS_INDEX_2.out.tbi - .mix(BCFTOOLS_INDEX_2.out.csi) - ) + ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants.join( + BCFTOOLS_INDEX_LIGATE.out.tbi.mix(BCFTOOLS_INDEX_LIGATE.out.csi), + failOnMismatch: true, + failOnDuplicate: true, + ) emit: - vcf_index = ch_vcf_index // channel: [ [id, chr], vcf, tbi ] - versions = ch_versions // channel: [ versions.yml ] - + vcf_index = ch_vcf_index // channel: [ [id, chr], vcf, tbi ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/bam_impute_stitch/tests/main.nf.test.snap b/subworkflows/nf-core/bam_impute_stitch/tests/main.nf.test.snap index 38244832ff5a..0e70d6beac65 100644 --- a/subworkflows/nf-core/bam_impute_stitch/tests/main.nf.test.snap +++ b/subworkflows/nf-core/bam_impute_stitch/tests/main.nf.test.snap @@ -17,30 +17,30 @@ ] ], [ - "versions.yml:md5,597985efae796d9efe8b1005c4b0bb18", "versions.yml:md5,8b0020b997bad45e9e3cf0d9b868a3b2", + "versions.yml:md5,a4f599fd82e75ff0d0d523a0b0c519ea", "versions.yml:md5,c32cdf9d543fe0fe8f0cfeade5ceade2", - "versions.yml:md5,d9282aba3ae921597b3a7387e17e220d" + "versions.yml:md5,fad02b5beb8bf43963d49e3b1e79f51d" ], [ - { - "BAM_IMPUTE_STITCH:BCFTOOLS_INDEX_2": { - "bcftools": 1.22 - } - }, { "BAM_IMPUTE_STITCH:STITCH": { "r-base": "4.4.2", "r-stitch": "1.7.3" } }, + { + "BAM_IMPUTE_STITCH:BCFTOOLS_INDEX_LIGATE": { + "bcftools": 1.22 + } + }, { "BAM_IMPUTE_STITCH:GLIMPSE2_LIGATE": { "glimpse2": "2.0.0" } }, { - "BAM_IMPUTE_STITCH:BCFTOOLS_INDEX_1": { + "BAM_IMPUTE_STITCH:BCFTOOLS_INDEX_PHASE": { "bcftools": 1.22 } } @@ -50,7 +50,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-27T09:22:32.971453937" + "timestamp": "2025-12-12T17:56:15.184463537" }, "homo_sapiens - empty channels - stub": { "content": [ @@ -74,10 +74,10 @@ ] ], "1": [ - "versions.yml:md5,597985efae796d9efe8b1005c4b0bb18", "versions.yml:md5,8b0020b997bad45e9e3cf0d9b868a3b2", + "versions.yml:md5,a4f599fd82e75ff0d0d523a0b0c519ea", "versions.yml:md5,c32cdf9d543fe0fe8f0cfeade5ceade2", - "versions.yml:md5,d9282aba3ae921597b3a7387e17e220d" + "versions.yml:md5,fad02b5beb8bf43963d49e3b1e79f51d" ], "vcf_index": [ [ @@ -98,31 +98,31 @@ ] ], "versions": [ - "versions.yml:md5,597985efae796d9efe8b1005c4b0bb18", "versions.yml:md5,8b0020b997bad45e9e3cf0d9b868a3b2", + "versions.yml:md5,a4f599fd82e75ff0d0d523a0b0c519ea", "versions.yml:md5,c32cdf9d543fe0fe8f0cfeade5ceade2", - "versions.yml:md5,d9282aba3ae921597b3a7387e17e220d" + "versions.yml:md5,fad02b5beb8bf43963d49e3b1e79f51d" ] }, [ - { - "BAM_IMPUTE_STITCH:BCFTOOLS_INDEX_2": { - "bcftools": 1.22 - } - }, { "BAM_IMPUTE_STITCH:STITCH": { "r-base": "4.4.2", "r-stitch": "1.7.3" } }, + { + "BAM_IMPUTE_STITCH:BCFTOOLS_INDEX_LIGATE": { + "bcftools": 1.22 + } + }, { "BAM_IMPUTE_STITCH:GLIMPSE2_LIGATE": { "glimpse2": "2.0.0" } }, { - "BAM_IMPUTE_STITCH:BCFTOOLS_INDEX_1": { + "BAM_IMPUTE_STITCH:BCFTOOLS_INDEX_PHASE": { "bcftools": 1.22 } } @@ -132,7 +132,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-21T22:32:30.735092649" + "timestamp": "2025-12-12T17:57:16.113125809" }, "Impute with stitch two individual bam, renaming, posfile, chunks, map, no fasta": { "content": [ @@ -167,24 +167,24 @@ ] ], [ - { - "BAM_IMPUTE_STITCH:BCFTOOLS_INDEX_2": { - "bcftools": 1.22 - } - }, { "BAM_IMPUTE_STITCH:STITCH": { "r-base": "4.4.2", "r-stitch": "1.7.3" } }, + { + "BAM_IMPUTE_STITCH:BCFTOOLS_INDEX_LIGATE": { + "bcftools": 1.22 + } + }, { "BAM_IMPUTE_STITCH:GLIMPSE2_LIGATE": { "glimpse2": "2.0.0" } }, { - "BAM_IMPUTE_STITCH:BCFTOOLS_INDEX_1": { + "BAM_IMPUTE_STITCH:BCFTOOLS_INDEX_PHASE": { "bcftools": 1.22 } } @@ -194,6 +194,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-27T10:28:44.112173975" + "timestamp": "2025-12-12T17:56:52.597711102" } } \ No newline at end of file diff --git a/subworkflows/nf-core/bam_impute_stitch/tests/nextflow.config b/subworkflows/nf-core/bam_impute_stitch/tests/nextflow.config index 976f2b6fe9e1..ffd2682816ab 100644 --- a/subworkflows/nf-core/bam_impute_stitch/tests/nextflow.config +++ b/subworkflows/nf-core/bam_impute_stitch/tests/nextflow.config @@ -1,6 +1,6 @@ process { withName: STITCH { - cpus = 1 // Needed to have deterministic output for testing + cpus = 1 // needed for deterministic output ext.prefix = { "${meta.id}_${meta.chr}_${meta.regionout}.stitch" } } @@ -8,11 +8,11 @@ process { ext.prefix = { "${meta.id}_${meta.chr}.ligate" } } - withName: BCFTOOLS_INDEX_1 { - ext.args = '--tbi' + withName: BCFTOOLS_INDEX_PHASE { + ext.args = '--tbi' } - withName: BCFTOOLS_INDEX_2 { - ext.args = '--csi' + withName: BCFTOOLS_INDEX_LIGATE { + ext.args = '--csi' } } diff --git a/subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf b/subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf index db11d1f534b3..c6062a1033c3 100644 --- a/subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf +++ b/subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf @@ -1,12 +1,11 @@ -include { GLIMPSE2_CHUNK } from '../../../modules/nf-core/glimpse2/chunk/main' -include { GLIMPSE2_SPLITREFERENCE } from '../../../modules/nf-core/glimpse2/splitreference/main' -include { GLIMPSE2_PHASE } from '../../../modules/nf-core/glimpse2/phase/main' -include { GLIMPSE2_LIGATE } from '../../../modules/nf-core/glimpse2/ligate/main' -include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_1 } from '../../../modules/nf-core/bcftools/index/main.nf' -include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_2 } from '../../../modules/nf-core/bcftools/index/main.nf' +include { GLIMPSE2_CHUNK } from '../../../modules/nf-core/glimpse2/chunk/main' +include { GLIMPSE2_SPLITREFERENCE } from '../../../modules/nf-core/glimpse2/splitreference/main' +include { GLIMPSE2_PHASE } from '../../../modules/nf-core/glimpse2/phase/main' +include { GLIMPSE2_LIGATE } from '../../../modules/nf-core/glimpse2/ligate/main' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_PHASE } from '../../../modules/nf-core/bcftools/index/main.nf' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_LIGATE } from '../../../modules/nf-core/bcftools/index/main.nf' workflow BAM_VCF_IMPUTE_GLIMPSE2 { - take: ch_input // channel (mandatory): [ meta, vcf, csi, list, infos ] ch_ref // channel (mandatory): [ meta, vcf, csi, region ] @@ -21,59 +20,73 @@ workflow BAM_VCF_IMPUTE_GLIMPSE2 { ch_versions = channel.empty() - if ( chunk == true ){ + if (chunk == true) { // Error if pre-defined chunks are provided when chunking is activated ch_chunks .filter { _meta, regionin, regionout -> regionin.size() == 0 && regionout.size() == 0 } .ifEmpty { - error "ERROR: Cannot provide pre-defined chunks (regionin) when chunk=true. Please either set chunk=false to use provided chunks, or remove input chunks to enable automatic chunking." + error("ERROR: Cannot provide pre-defined chunks (regionin) when chunk=true. Please either set chunk=false to use provided chunks, or remove input chunks to enable automatic chunking.") } // Chunk reference panel - ch_ref_map = ch_ref - .combine(ch_map, by: 0) - GLIMPSE2_CHUNK ( ch_ref_map, chunk_model ) - ch_versions = ch_versions.mix( GLIMPSE2_CHUNK.out.versions.first() ) + ch_ref_map = ch_ref.combine(ch_map, by: 0) + GLIMPSE2_CHUNK(ch_ref_map, chunk_model) + ch_versions = ch_versions.mix(GLIMPSE2_CHUNK.out.versions.first()) ch_chunks = GLIMPSE2_CHUNK.out.chunk_chr - .splitCsv(header: [ - 'ID', 'Chr', 'RegionBuf', 'RegionCnk', 'WindowCm', - 'WindowMb', 'NbTotVariants', 'NbComVariants' - ], sep: "\t", skip: 0) - .map { meta, it -> [meta, it["RegionBuf"], it["RegionCnk"]]} + .splitCsv( + header: [ + 'ID', 'Chr', + 'RegionBuf', 'RegionCnk', + 'WindowCm', 'WindowMb', + 'NbTotVariants', 'NbComVariants', + ], + sep: "\t", + skip: 0, + ) + .map { meta, it -> [meta, it["RegionBuf"], it["RegionCnk"]] } } ch_chunks .filter { _meta, regionin, regionout -> regionin.size() > 0 && regionout.size() > 0 } - .ifEmpty { error "ERROR: ch_chunks channel is empty. Please provide a valid channel or set chunk parameter to true." } + .ifEmpty { error("ERROR: ch_chunks channel is empty. Please provide a valid channel or set chunk parameter to true.") } - if ( splitreference == true ) { + if (splitreference == true) { // Split reference panel in bin files split_input = ch_ref .combine(ch_chunks, by: 0) .combine(ch_map, by: 0) - .map{ meta, ref, index, _region, regionin, regionout, gmap -> [ - meta + ["regionin": regionin, "regionout": regionout], - ref, index, regionin, regionout, gmap - ] } + .map { meta, ref, index, _region, regionin, regionout, gmap -> + [ + meta + ["regionin": regionin, "regionout": regionout], + ref, index, + regionin, regionout, + gmap, + ] + } - GLIMPSE2_SPLITREFERENCE( split_input ) - ch_versions = ch_versions.mix( GLIMPSE2_SPLITREFERENCE.out.versions.first() ) + GLIMPSE2_SPLITREFERENCE(split_input) + ch_versions = ch_versions.mix(GLIMPSE2_SPLITREFERENCE.out.versions.first()) + // Everything is provided by the bin file so no additional file ch_chunks_panel_map = GLIMPSE2_SPLITREFERENCE.out.bin_ref - .map{ meta, bin_ref -> [ meta, [], [], bin_ref, [], [] ] } // Everything is provided by the bin file + .map { meta, bin_ref -> [meta, [], [], bin_ref, [], []] } } else { ch_chunks_panel_map = ch_chunks - .combine(ch_ref, by:0) - .combine(ch_map, by:0) - .map{ meta, regionin, regionout, ref, ref_index, _region, gmap -> [ - meta + ["regionin": regionin, "regionout": regionout], - regionin, regionout, ref, ref_index, gmap - ] } + .combine(ch_ref, by: 0) + .combine(ch_map, by: 0) + .map { meta, regionin, regionout, ref, ref_index, _region, gmap -> + [ + meta + ["regionin": regionin, "regionout": regionout], + regionin, regionout, + ref, ref_index, + gmap, + ] + } } - ch_chunks_panel_map.ifEmpty{ - error "ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input." + ch_chunks_panel_map.ifEmpty { + error("ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input.") } ch_phase_input = ch_input @@ -87,37 +100,40 @@ workflow BAM_VCF_IMPUTE_GLIMPSE2 { // Impute with Glimpse2 GLIMPSE2_PHASE(ch_phase_input, ch_fasta) - ch_versions = ch_versions.mix( GLIMPSE2_PHASE.out.versions.first() ) + ch_versions = ch_versions.mix(GLIMPSE2_PHASE.out.versions.first()) // Index phased file - BCFTOOLS_INDEX_1(GLIMPSE2_PHASE.out.phased_variants) - ch_versions = ch_versions.mix( BCFTOOLS_INDEX_1.out.versions.first() ) + BCFTOOLS_INDEX_PHASE(GLIMPSE2_PHASE.out.phased_variants.view()) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_PHASE.out.versions.first()) // Ligate all phased files in one and index it ligate_input = GLIMPSE2_PHASE.out.phased_variants - .join( BCFTOOLS_INDEX_1.out.csi ) - .map{ meta, vcf, index -> + .join( + BCFTOOLS_INDEX_PHASE.out.tbi.mix(BCFTOOLS_INDEX_PHASE.out.csi).view(), + failOnMismatch: true, + failOnDuplicate: true, + ) + .map { meta, vcf, index -> def keysToKeep = meta.keySet() - ['regionin', 'regionout'] - [ meta.subMap(keysToKeep), vcf, index ] + [meta.subMap(keysToKeep), vcf, index] } .groupTuple() - GLIMPSE2_LIGATE( ligate_input ) - ch_versions = ch_versions.mix( GLIMPSE2_LIGATE.out.versions.first() ) + GLIMPSE2_LIGATE(ligate_input) + ch_versions = ch_versions.mix(GLIMPSE2_LIGATE.out.versions.first()) - BCFTOOLS_INDEX_2( GLIMPSE2_LIGATE.out.merged_variants ) - ch_versions = ch_versions.mix( BCFTOOLS_INDEX_2.out.versions.first() ) + BCFTOOLS_INDEX_LIGATE(GLIMPSE2_LIGATE.out.merged_variants) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_LIGATE.out.versions.first()) // Join imputed and index files - ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants - .join( - BCFTOOLS_INDEX_2.out.tbi - .mix(BCFTOOLS_INDEX_2.out.csi) - ) + ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants.join( + BCFTOOLS_INDEX_LIGATE.out.tbi.mix(BCFTOOLS_INDEX_LIGATE.out.csi), + failOnMismatch: true, + failOnDuplicate: true, + ) emit: - ch_chunks = ch_chunks // channel: [ val(meta), regionin, regionout ] - ch_vcf_index = ch_vcf_index // channel: [ val(meta), vcf, csi ] - - versions = ch_versions // channel: [ versions.yml ] + chunks = ch_chunks // channel: [ val(meta), regionin, regionout ] + vcf_index = ch_vcf_index // channel: [ val(meta), vcf, csi ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test index 15ed651546b1..8dfcd024f8aa 100644 --- a/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test +++ b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test @@ -55,8 +55,8 @@ nextflow_workflow { assertAll( { assert workflow.success }, { assert snapshot( - workflow.out.ch_chunks, - workflow.out.ch_vcf_index.collect{[ + workflow.out.chunks, + workflow.out.vcf_index.collect{[ it[0], path(it[1]).getFileName().toString(), path(it[2]).getFileName().toString(), @@ -109,8 +109,8 @@ nextflow_workflow { assertAll( { assert workflow.success }, { assert snapshot( - workflow.out.ch_chunks, - workflow.out.ch_vcf_index.collect{[ + workflow.out.chunks, + workflow.out.vcf_index.collect{[ it[0], path(it[1]).getFileName().toString(), path(it[2]).getFileName().toString(), @@ -163,8 +163,8 @@ nextflow_workflow { assertAll( { assert workflow.success }, { assert snapshot( - workflow.out.ch_chunks, - workflow.out.ch_vcf_index.collect{[ + workflow.out.chunks, + workflow.out.vcf_index.collect{[ it[0], path(it[1]).getFileName().toString(), path(it[2]).getFileName().toString(), @@ -214,8 +214,8 @@ nextflow_workflow { assertAll( { assert workflow.success }, { assert snapshot( - workflow.out.ch_chunks, - workflow.out.ch_vcf_index.collect{[ + workflow.out.chunks, + workflow.out.vcf_index.collect{[ it[0], path(it[1]).getFileName().toString(), path(it[2]).getFileName().toString(), @@ -282,8 +282,8 @@ nextflow_workflow { assertAll( { assert workflow.success }, { assert snapshot( - workflow.out.ch_chunks, - workflow.out.ch_vcf_index.collect{[ + workflow.out.chunks, + workflow.out.vcf_index.collect{[ it[0], path(it[1]).getFileName().toString(), path(it[2]).getFileName().toString(), diff --git a/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test.snap b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test.snap index d7e3e862c1e0..bea3ca6317ca 100644 --- a/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test.snap +++ b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/main.nf.test.snap @@ -36,6 +36,11 @@ ] ], [ + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_PHASE": { + "bcftools": 1.22 + } + }, { "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_CHUNK": { "glimpse2": "2.0.0" @@ -47,7 +52,7 @@ } }, { - "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_2": { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_LIGATE": { "bcftools": 1.22 } }, @@ -56,11 +61,6 @@ "glimpse2": "2.0.0" } }, - { - "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_1": { - "bcftools": 1.22 - } - }, { "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_SPLITREFERENCE": { "glimpse2": "2.0.0" @@ -72,7 +72,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-21T12:07:17.825740137" + "timestamp": "2025-12-12T17:46:53.105738111" }, "homo_sapiens - bam no list and no sample, panel vcf region, no chunks, no map, no fasta, chunk sequential + splitreference": { "content": [ @@ -111,6 +111,11 @@ ] ], [ + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_PHASE": { + "bcftools": 1.22 + } + }, { "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_CHUNK": { "glimpse2": "2.0.0" @@ -122,7 +127,7 @@ } }, { - "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_2": { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_LIGATE": { "bcftools": 1.22 } }, @@ -131,11 +136,6 @@ "glimpse2": "2.0.0" } }, - { - "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_1": { - "bcftools": 1.22 - } - }, { "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_SPLITREFERENCE": { "glimpse2": "2.0.0" @@ -147,7 +147,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-21T12:08:29.707313034" + "timestamp": "2025-12-12T17:47:45.080376306" }, "homo_sapiens - empty channels, chunk sequential + splitreference - stub": { "content": [ @@ -191,14 +191,14 @@ ] ], "2": [ + "versions.yml:md5,127e1dce80da79a92d0b685e82095c4a", "versions.yml:md5,302281bbff76712870c031340d3819ff", "versions.yml:md5,3500318c881e3f24e9dd2fddc593142a", - "versions.yml:md5,9422ca169a15fd68878396c2837bc185", + "versions.yml:md5,6f1e64d5b987d61d5a718c0fba06e230", "versions.yml:md5,c6ff81aa44fb2fdcc08db6062731d0d9", - "versions.yml:md5,cb51e18b4296c3791ade5f6f2737bd24", "versions.yml:md5,ed6ebcf6ca30c2cdc39ec1dd535a2695" ], - "ch_chunks": [ + "chunks": [ [ { "panel": "ref_panel", @@ -216,7 +216,7 @@ "0" ] ], - "ch_vcf_index": [ + "vcf_index": [ [ { "id": "allid", @@ -237,15 +237,20 @@ ] ], "versions": [ + "versions.yml:md5,127e1dce80da79a92d0b685e82095c4a", "versions.yml:md5,302281bbff76712870c031340d3819ff", "versions.yml:md5,3500318c881e3f24e9dd2fddc593142a", - "versions.yml:md5,9422ca169a15fd68878396c2837bc185", + "versions.yml:md5,6f1e64d5b987d61d5a718c0fba06e230", "versions.yml:md5,c6ff81aa44fb2fdcc08db6062731d0d9", - "versions.yml:md5,cb51e18b4296c3791ade5f6f2737bd24", "versions.yml:md5,ed6ebcf6ca30c2cdc39ec1dd535a2695" ] }, [ + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_PHASE": { + "bcftools": 1.22 + } + }, { "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_CHUNK": { "glimpse2": "2.0.0" @@ -257,7 +262,7 @@ } }, { - "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_2": { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_LIGATE": { "bcftools": 1.22 } }, @@ -266,11 +271,6 @@ "glimpse2": "2.0.0" } }, - { - "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_1": { - "bcftools": 1.22 - } - }, { "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_SPLITREFERENCE": { "glimpse2": "2.0.0" @@ -282,7 +282,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-21T12:10:17.321588787" + "timestamp": "2025-12-12T17:48:24.153179179" }, "homo_sapiens - vcf no list with sample, panel vcf region, chunks, map, no fasta, no chunking + no splitreference": { "content": [ @@ -321,13 +321,18 @@ ] ], [ + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_PHASE": { + "bcftools": 1.22 + } + }, { "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_PHASE": { "glimpse2": "2.0.0" } }, { - "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_2": { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_LIGATE": { "bcftools": 1.22 } }, @@ -335,11 +340,6 @@ "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_LIGATE": { "glimpse2": "2.0.0" } - }, - { - "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_1": { - "bcftools": 1.22 - } } ] ], @@ -347,7 +347,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-21T12:08:13.222110779" + "timestamp": "2025-12-12T17:47:25.417111147" }, "homo_sapiens - vcf no list with sample, panel vcf region, chunks, map, no fasta, no chunking + splitreference": { "content": [ @@ -386,13 +386,18 @@ ] ], [ + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_PHASE": { + "bcftools": 1.22 + } + }, { "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_PHASE": { "glimpse2": "2.0.0" } }, { - "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_2": { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_LIGATE": { "bcftools": 1.22 } }, @@ -401,11 +406,6 @@ "glimpse2": "2.0.0" } }, - { - "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_1": { - "bcftools": 1.22 - } - }, { "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_SPLITREFERENCE": { "glimpse2": "2.0.0" @@ -417,7 +417,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-11-21T12:07:58.812913099" + "timestamp": "2025-12-12T17:47:10.50028164" }, "homo_sapiens - bam list and sample, panel vcf region, chunks, map, no fasta, no chunking + splitreference": { "content": [ @@ -488,13 +488,18 @@ ] ], [ + { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_PHASE": { + "bcftools": 1.22 + } + }, { "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_PHASE": { "glimpse2": "2.0.0" } }, { - "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_2": { + "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_LIGATE": { "bcftools": 1.22 } }, @@ -503,11 +508,6 @@ "glimpse2": "2.0.0" } }, - { - "BAM_VCF_IMPUTE_GLIMPSE2:BCFTOOLS_INDEX_1": { - "bcftools": 1.22 - } - }, { "BAM_VCF_IMPUTE_GLIMPSE2:GLIMPSE2_SPLITREFERENCE": { "glimpse2": "2.0.0" @@ -519,6 +519,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-12-08T19:39:08.135355223" + "timestamp": "2025-12-12T17:48:08.11043848" } } \ No newline at end of file diff --git a/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/nextflow.config b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/nextflow.config index 9cd201b85a2a..7aea8a877175 100644 --- a/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/nextflow.config +++ b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/nextflow.config @@ -1,41 +1,41 @@ process { - withName: "GLIMPSE2_CHUNK" { + withName: GLIMPSE2_CHUNK { ext.prefix = { "${meta.panel}_${meta.chr}" } - tag = { "${meta.panel} ${meta.chr}}" } - ext.args = [ + tag = { "${meta.panel} ${meta.chr}}" } + ext.args = [ "--window-mb 0.01", "--window-cm 0.01", "--window-count 200", "--buffer-mb 0.005", "--buffer-cm 0.005", "--buffer-count 30", - "--seed 1" + "--seed 1", ].join(' ') } - withName: "GLIMPSE2_SPLITREFERENCE" { + withName: GLIMPSE2_SPLITREFERENCE { ext.prefix = { "${meta.panel}_${meta.chr}_${meta.regionout}" } - tag = { "${meta.panel} ${meta.chr} ${meta.regionout}" } - ext.args = "--seed 1" + tag = { "${meta.panel} ${meta.chr} ${meta.regionout}" } + ext.args = "--seed 1" } - withName: "GLIMPSE2_PHASE" { + withName: GLIMPSE2_PHASE { ext.prefix = { "${meta.id}_${meta.chr}_${meta.regionout}" } - tag = { "${meta.id} ${meta.chr} ${meta.regionout}" } - cpus = 1 - ext.args = "--keep-monomorphic-ref-sites --seed 1" + tag = { "${meta.id} ${meta.chr} ${meta.regionout}" } + cpus = 1 // needed for deterministic output + ext.args = "--keep-monomorphic-ref-sites --seed 1" } - withName: "BCFTOOLS_INDEX_1" { + withName: BCFTOOLS_INDEX_PHASE { tag = { "${meta.id} ${meta.chr} ${meta.regionout}" } } - withName: "GLIMPSE2_LIGATE" { + withName: GLIMPSE2_LIGATE { ext.prefix = { "${meta.id}_${meta.chr}" } - tag = { "${meta.id} ${meta.chr}" } + tag = { "${meta.id} ${meta.chr}" } } - withName: "BCFTOOLS_INDEX_2" { + withName: BCFTOOLS_INDEX_LIGATE { tag = { "${meta.id} ${meta.chr}" } } } diff --git a/subworkflows/nf-core/vcf_impute_beagle5/main.nf b/subworkflows/nf-core/vcf_impute_beagle5/main.nf index 3ccb03229b61..2f79dec4afb0 100644 --- a/subworkflows/nf-core/vcf_impute_beagle5/main.nf +++ b/subworkflows/nf-core/vcf_impute_beagle5/main.nf @@ -1,11 +1,10 @@ include { BEAGLE5_BEAGLE } from '../../../modules/nf-core/beagle5/beagle' include { BCFTOOLS_VIEW } from '../../../modules/nf-core/bcftools/view' include { GLIMPSE2_LIGATE } from '../../../modules/nf-core/glimpse2/ligate' -include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_BEAGLE } from '../../../modules/nf-core/bcftools/index' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_PHASE } from '../../../modules/nf-core/bcftools/index' include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_LIGATE } from '../../../modules/nf-core/bcftools/index' workflow VCF_IMPUTE_BEAGLE5 { - take: ch_input // channel (mandatory): [ [id], vcf, tbi ] ch_panel // channel (mandatory): [ [panel, chr], vcf, tbi ] @@ -24,8 +23,8 @@ workflow VCF_IMPUTE_BEAGLE5 { } .set { ch_input_branched } - ch_input_branched.other.map{ _meta, vcf, _tbi -> - error "ERROR: ${vcf.name} in ch_input channel must be in VCF or BCF format." + ch_input_branched.other.map { _meta, vcf, _tbi -> + error("ERROR: ${vcf.name} in ch_input channel must be in VCF or BCF format.") } // Convert BCF to VCF if necessary @@ -36,13 +35,13 @@ workflow VCF_IMPUTE_BEAGLE5 { ch_versions = ch_versions.mix(BCFTOOLS_VIEW.out.versions.first()) // Combine VCF files - ch_ready_vcf = ch_input_branched.vcf - .mix(BCFTOOLS_VIEW.out.vcf - .join( - BCFTOOLS_VIEW.out.csi - .mix(BCFTOOLS_VIEW.out.tbi) - ) + ch_ready_vcf = ch_input_branched.vcf.mix( + BCFTOOLS_VIEW.out.vcf.join( + BCFTOOLS_VIEW.out.tbi.mix(BCFTOOLS_VIEW.out.csi), + failOnMismatch: true, + failOnDuplicate: true, ) + ) // Prepare input channels for BEAGLE5 by combining VCF, panel, and map files ch_chunks_counts = ch_chunks @@ -56,61 +55,66 @@ workflow VCF_IMPUTE_BEAGLE5 { .combine(ch_chunks, by: 0) .combine(ch_chunks_counts, by: 0) - ch_panel_map.ifEmpty{ - error "ERROR: join operation resulted in an empty channel. Please provide a valid ch_panel and ch_map channel as input." + ch_panel_map.ifEmpty { + error("ERROR: join operation resulted in an empty channel. Please provide a valid ch_panel and ch_map channel as input.") } ch_beagle_input = ch_ready_vcf .combine(ch_panel_map) - .map { metaI, input_vcf, input_index, metaPC, panel_vcf, panel_index, map, regionout, regionsize -> [ - metaI + metaPC + ["regionout": regionout, "regionsize": regionsize], - input_vcf, input_index, - panel_vcf, panel_index, - map, [], [], regionout - ]} + .map { metaI, input_vcf, input_index, metaPC, panel_vcf, panel_index, map, regionout, regionsize -> + [ + metaI + metaPC + ["regionout": regionout, "regionsize": regionsize], + input_vcf, input_index, + panel_vcf, panel_index, + map, + [], [], + regionout, + ] + } // Run BEAGLE5 imputation BEAGLE5_BEAGLE(ch_beagle_input) ch_versions = ch_versions.mix(BEAGLE5_BEAGLE.out.versions.first()) // Index the imputed VCF files - BCFTOOLS_INDEX_BEAGLE(BEAGLE5_BEAGLE.out.vcf) - ch_versions = ch_versions.mix(BCFTOOLS_INDEX_BEAGLE.out.versions.first()) + BCFTOOLS_INDEX_PHASE(BEAGLE5_BEAGLE.out.vcf) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_PHASE.out.versions.first()) // Ligate all phased files in one and index it ligate_input = BEAGLE5_BEAGLE.out.vcf .join( - BCFTOOLS_INDEX_BEAGLE.out.tbi - .mix(BCFTOOLS_INDEX_BEAGLE.out.csi) + BCFTOOLS_INDEX_PHASE.out.tbi.mix(BCFTOOLS_INDEX_PHASE.out.csi), + failOnMismatch: true, + failOnDuplicate: true, ) - .map{ meta, vcf, index -> + .map { meta, vcf, index -> def keysToKeep = meta.keySet() - ['regionout', 'regionsize'] [ groupKey(meta.subMap(keysToKeep), meta.regionsize), - vcf, index + vcf, index, ] } .groupTuple() - .map{ groupKeyObj, vcf, index -> + .map { groupKeyObj, vcf, index -> // Extract the actual meta from the groupKey def meta = groupKeyObj.getGroupTarget() [meta, vcf, index] } - GLIMPSE2_LIGATE( ligate_input ) - ch_versions = ch_versions.mix( GLIMPSE2_LIGATE.out.versions.first() ) + GLIMPSE2_LIGATE(ligate_input) + ch_versions = ch_versions.mix(GLIMPSE2_LIGATE.out.versions.first()) - BCFTOOLS_INDEX_LIGATE( GLIMPSE2_LIGATE.out.merged_variants ) - ch_versions = ch_versions.mix( BCFTOOLS_INDEX_LIGATE.out.versions.first() ) + BCFTOOLS_INDEX_LIGATE(GLIMPSE2_LIGATE.out.merged_variants) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_LIGATE.out.versions.first()) // Join imputed and index files - ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants - .join( - BCFTOOLS_INDEX_LIGATE.out.tbi - .mix(BCFTOOLS_INDEX_LIGATE.out.csi) - ) + ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants.join( + BCFTOOLS_INDEX_LIGATE.out.tbi.mix(BCFTOOLS_INDEX_LIGATE.out.csi), + failOnMismatch: true, + failOnDuplicate: true, + ) emit: - vcf_index = ch_vcf_index // channel: [ [id, chr, tools], vcf, index ] - versions = ch_versions // channel: [ versions.yml ] + vcf_index = ch_vcf_index // channel: [ [id, chr, tools], vcf, index ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/vcf_impute_beagle5/tests/main.nf.test.snap b/subworkflows/nf-core/vcf_impute_beagle5/tests/main.nf.test.snap index 36c113694362..035cee7fbad9 100644 --- a/subworkflows/nf-core/vcf_impute_beagle5/tests/main.nf.test.snap +++ b/subworkflows/nf-core/vcf_impute_beagle5/tests/main.nf.test.snap @@ -18,20 +18,20 @@ ] ], [ - "versions.yml:md5,055ba50f00b32df929e0e147ba6d4408", "versions.yml:md5,3ba3affc995d9a03ef59f8cf9e7fac38", + "versions.yml:md5,a4740debfa9b03fbd4cd094f1d5ff5d0", "versions.yml:md5,e4c10555396b9a57ef3aafc9a4707963", "versions.yml:md5,ff3101d4f934dc550b466d79e092707c" ], [ { - "VCF_IMPUTE_BEAGLE5:BCFTOOLS_INDEX_BEAGLE": { - "bcftools": 1.22 + "VCF_IMPUTE_BEAGLE5:BEAGLE5_BEAGLE": { + "beagle": "5.5rev27Feb25.75f" } }, { - "VCF_IMPUTE_BEAGLE5:BEAGLE5_BEAGLE": { - "beagle": "5.5rev27Feb25.75f" + "VCF_IMPUTE_BEAGLE5:BCFTOOLS_INDEX_PHASE": { + "bcftools": 1.22 } }, { @@ -50,7 +50,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-12-11T10:40:58.515114119" + "timestamp": "2025-12-12T18:12:49.389456693" }, "homo_sapiens - empty channels - stub": { "content": [ @@ -76,8 +76,8 @@ ] ], "1": [ - "versions.yml:md5,055ba50f00b32df929e0e147ba6d4408", "versions.yml:md5,3ba3affc995d9a03ef59f8cf9e7fac38", + "versions.yml:md5,a4740debfa9b03fbd4cd094f1d5ff5d0", "versions.yml:md5,e4c10555396b9a57ef3aafc9a4707963", "versions.yml:md5,ff3101d4f934dc550b466d79e092707c" ], @@ -102,21 +102,21 @@ ] ], "versions": [ - "versions.yml:md5,055ba50f00b32df929e0e147ba6d4408", "versions.yml:md5,3ba3affc995d9a03ef59f8cf9e7fac38", + "versions.yml:md5,a4740debfa9b03fbd4cd094f1d5ff5d0", "versions.yml:md5,e4c10555396b9a57ef3aafc9a4707963", "versions.yml:md5,ff3101d4f934dc550b466d79e092707c" ] }, [ { - "VCF_IMPUTE_BEAGLE5:BCFTOOLS_INDEX_BEAGLE": { - "bcftools": 1.22 + "VCF_IMPUTE_BEAGLE5:BEAGLE5_BEAGLE": { + "beagle": "5.5rev27Feb25.75f" } }, { - "VCF_IMPUTE_BEAGLE5:BEAGLE5_BEAGLE": { - "beagle": "5.5rev27Feb25.75f" + "VCF_IMPUTE_BEAGLE5:BCFTOOLS_INDEX_PHASE": { + "bcftools": 1.22 } }, { @@ -135,7 +135,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-12-11T10:37:59.303608442" + "timestamp": "2025-12-12T18:14:04.06517785" }, "Impute with beagle5 one bcf gz - panel - map - chunks - two chrosomes": { "content": [ @@ -171,13 +171,13 @@ ], [ { - "VCF_IMPUTE_BEAGLE5:BCFTOOLS_INDEX_BEAGLE": { - "bcftools": 1.22 + "VCF_IMPUTE_BEAGLE5:BEAGLE5_BEAGLE": { + "beagle": "5.5rev27Feb25.75f" } }, { - "VCF_IMPUTE_BEAGLE5:BEAGLE5_BEAGLE": { - "beagle": "5.5rev27Feb25.75f" + "VCF_IMPUTE_BEAGLE5:BCFTOOLS_INDEX_PHASE": { + "bcftools": 1.22 } }, { @@ -201,6 +201,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-12-11T10:41:17.021023357" + "timestamp": "2025-12-12T18:13:48.934880404" } } \ No newline at end of file diff --git a/subworkflows/nf-core/vcf_impute_beagle5/tests/nextflow.config b/subworkflows/nf-core/vcf_impute_beagle5/tests/nextflow.config index 9be75a1c7cb9..5b205b5e388a 100644 --- a/subworkflows/nf-core/vcf_impute_beagle5/tests/nextflow.config +++ b/subworkflows/nf-core/vcf_impute_beagle5/tests/nextflow.config @@ -1,6 +1,6 @@ process { withName: BCFTOOLS_VIEW { - ext.args = { "--write-index=tbi --output-type z" } + ext.args = { "--write-index=tbi --output-type z" } } withName: BEAGLE5_BEAGLE { @@ -11,15 +11,15 @@ process { ext.prefix = { "${meta.id}_${meta.chr}.ligate" } } - withName: BCFTOOLS_INDEX_BEAGLE { - ext.args = '--tbi' + withName: BCFTOOLS_INDEX_PHASE { + ext.args = '--tbi' } withName: BCFTOOLS_INDEX_LIGATE { - ext.args = '--csi' + ext.args = '--csi' } withName: BCFTOOLS_VIEW_BCF { - ext.args = { params.bcftools_view_args ?: "" } + ext.args = { params.bcftools_view_args ?: "" } } } diff --git a/subworkflows/nf-core/vcf_impute_glimpse/main.nf b/subworkflows/nf-core/vcf_impute_glimpse/main.nf index 9bfce0652756..f1dc049c722d 100644 --- a/subworkflows/nf-core/vcf_impute_glimpse/main.nf +++ b/subworkflows/nf-core/vcf_impute_glimpse/main.nf @@ -1,46 +1,45 @@ -include { GLIMPSE_CHUNK } from '../../../modules/nf-core/glimpse/chunk/main' -include { GLIMPSE_PHASE } from '../../../modules/nf-core/glimpse/phase/main' -include { GLIMPSE_LIGATE } from '../../../modules/nf-core/glimpse/ligate/main' -include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_PHASE } from '../../../modules/nf-core/bcftools/index/main.nf' +include { GLIMPSE_CHUNK } from '../../../modules/nf-core/glimpse/chunk/main' +include { GLIMPSE_PHASE } from '../../../modules/nf-core/glimpse/phase/main' +include { GLIMPSE_LIGATE } from '../../../modules/nf-core/glimpse/ligate/main' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_PHASE } from '../../../modules/nf-core/bcftools/index/main.nf' include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_LIGATE } from '../../../modules/nf-core/bcftools/index/main.nf' workflow VCF_IMPUTE_GLIMPSE { - take: - ch_vcf // channel (mandatory): [ meta, vcf, csi, infos ] - ch_ref // channel (mandatory): [ meta, vcf, csi, region ] - ch_chunks // channel (optional) : [ meta, regionin, regionout ] - ch_map // channel (optional) : [ meta, map ] - chunk // val (optional) : boolean to activate/deactivate chunking step + ch_vcf // channel (mandatory): [ meta, vcf, csi, infos ] + ch_ref // channel (mandatory): [ meta, vcf, csi, region ] + ch_chunks // channel (optional) : [ meta, regionin, regionout ] + ch_map // channel (optional) : [ meta, map ] + chunk // val (optional) : boolean to activate/deactivate chunking step main: ch_versions = channel.empty() - if ( chunk == true ){ + if (chunk == true) { // Error if pre-defined chunks are provided when chunking is activated ch_chunks .filter { _meta, regionin, regionout -> regionin.size() == 0 && regionout.size() == 0 } - .ifEmpty { error "ERROR: Cannot provide pre-defined chunks (regionin) when chunk=true. Please either set chunk=false to use provided chunks, or remove input chunks to enable automatic chunking." } + .ifEmpty { error("ERROR: Cannot provide pre-defined chunks (regionin) when chunk=true. Please either set chunk=false to use provided chunks, or remove input chunks to enable automatic chunking.") } - GLIMPSE_CHUNK ( ch_ref ) - ch_versions = ch_versions.mix( GLIMPSE_CHUNK.out.versions.first() ) + GLIMPSE_CHUNK(ch_ref) + ch_versions = ch_versions.mix(GLIMPSE_CHUNK.out.versions.first()) ch_chunks = GLIMPSE_CHUNK.out.chunk_chr .splitCsv(header: ['ID', 'Chr', 'RegionIn', 'RegionOut', 'Size1', 'Size2'], sep: "\t", skip: 0) - .map { meta, it -> [meta, it["RegionIn"], it["RegionOut"]]} + .map { meta, it -> [meta, it["RegionIn"], it["RegionOut"]] } } ch_chunks .filter { _meta, regionin, regionout -> regionin.size() > 0 && regionout.size() > 0 } - .ifEmpty { error "ERROR: ch_chunks channel is empty. Please provide a valid channel or set chunk parameter to true." } + .ifEmpty { error("ERROR: ch_chunks channel is empty. Please provide a valid channel or set chunk parameter to true.") } ch_chunks_panel_map = ch_chunks .combine(ch_ref, by: 0) .combine(ch_map, by: 0) - ch_chunks_panel_map.ifEmpty{ - error "ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input." + ch_chunks_panel_map.ifEmpty { + error("ERROR: join operation resulted in an empty channel. Please provide a valid ch_chunks and ch_map channel as input.") } phase_input = ch_vcf @@ -52,39 +51,40 @@ workflow VCF_IMPUTE_GLIMPSE { ref, ref_index, map // reference panel ]} - GLIMPSE_PHASE ( phase_input ) - ch_versions = ch_versions.mix(GLIMPSE_PHASE.out.versions.first() ) + GLIMPSE_PHASE(phase_input) + ch_versions = ch_versions.mix(GLIMPSE_PHASE.out.versions.first()) - BCFTOOLS_INDEX_PHASE ( GLIMPSE_PHASE.out.phased_variants ) - ch_versions = ch_versions.mix( BCFTOOLS_INDEX_PHASE.out.versions.first() ) + BCFTOOLS_INDEX_PHASE(GLIMPSE_PHASE.out.phased_variants) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_PHASE.out.versions.first()) // Ligate all phased files in one and index it ligate_input = GLIMPSE_PHASE.out.phased_variants - .join( BCFTOOLS_INDEX_PHASE.out.csi - .mix(BCFTOOLS_INDEX_PHASE.out.tbi) + .join( + BCFTOOLS_INDEX_PHASE.out.tbi.mix(BCFTOOLS_INDEX_PHASE.out.csi), + failOnMismatch: true, + failOnDuplicate: true, ) - .map{ meta, vcf, index -> + .map { meta, vcf, index -> def keysToKeep = meta.keySet() - 'regionout' - [ meta.subMap(keysToKeep), vcf, index ] + [meta.subMap(keysToKeep), vcf, index] } .groupTuple() - GLIMPSE_LIGATE ( ligate_input ) - ch_versions = ch_versions.mix(GLIMPSE_LIGATE.out.versions.first() ) + GLIMPSE_LIGATE(ligate_input) + ch_versions = ch_versions.mix(GLIMPSE_LIGATE.out.versions.first()) - BCFTOOLS_INDEX_LIGATE ( GLIMPSE_LIGATE.out.merged_variants ) - ch_versions = ch_versions.mix( BCFTOOLS_INDEX_LIGATE.out.versions.first() ) + BCFTOOLS_INDEX_LIGATE(GLIMPSE_LIGATE.out.merged_variants) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_LIGATE.out.versions.first()) // Join imputed and index files - ch_vcf_index = GLIMPSE_LIGATE.out.merged_variants - .join( - BCFTOOLS_INDEX_LIGATE.out.tbi - .mix(BCFTOOLS_INDEX_LIGATE.out.csi) - ) + ch_vcf_index = GLIMPSE_LIGATE.out.merged_variants.join( + BCFTOOLS_INDEX_LIGATE.out.tbi.mix(BCFTOOLS_INDEX_LIGATE.out.csi), + failOnMismatch: true, + failOnDuplicate: true, + ) emit: - chunk_chr = ch_chunks // channel: [ val(meta), regionin, regionout ] - vcf_index = ch_vcf_index // channel: [ val(meta), vcf, index ] - - versions = ch_versions // channel: [ versions.yml ] + chunks = ch_chunks // channel: [ val(meta), regionin, regionout ] + vcf_index = ch_vcf_index // channel: [ val(meta), vcf, index ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test b/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test index 8cc3387d17d7..3656070ec8af 100644 --- a/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test +++ b/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test @@ -51,7 +51,7 @@ nextflow_workflow { { assert workflow.success }, { assert snapshot( workflow.out.versions, - workflow.out.chunk_chr, + workflow.out.chunks, workflow.out.vcf_index.collect{ meta, vcf, index -> [ meta, path(vcf).getFileName().toString(), @@ -103,7 +103,7 @@ nextflow_workflow { { assert workflow.success }, { assert snapshot( workflow.out.versions, - workflow.out.chunk_chr, + workflow.out.chunks, workflow.out.vcf_index.collect{ meta, vcf, index -> [ meta, path(vcf).getFileName().toString(), diff --git a/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test.snap b/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test.snap index d6371b1f5d4b..4807e250d6aa 100644 --- a/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test.snap +++ b/subworkflows/nf-core/vcf_impute_glimpse/tests/main.nf.test.snap @@ -128,7 +128,7 @@ "versions.yml:md5,9fbf16c8cc7fbd7c71287273e4574c63", "versions.yml:md5,aaac5faff61fcbf4cc1aea0fdbd824ee" ], - "chunk_chr": [ + "chunks": [ [ { "panel": "ref_panel", diff --git a/subworkflows/nf-core/vcf_impute_glimpse/tests/nextflow.config b/subworkflows/nf-core/vcf_impute_glimpse/tests/nextflow.config index 8f4ae66f5bc4..30f9e1d3d566 100644 --- a/subworkflows/nf-core/vcf_impute_glimpse/tests/nextflow.config +++ b/subworkflows/nf-core/vcf_impute_glimpse/tests/nextflow.config @@ -1,10 +1,10 @@ process { withName: GLIMPSE_CHUNK { ext.prefix = { "${meta.panel}_${meta.chr}_chunk" } - ext.args = "--window-size 50000 --buffer-size 1000" + ext.args = "--window-size 50000 --buffer-size 1000" } withName: GLIMPSE_PHASE { - ext.prefix = { "${meta.id}_${meta.regionout? meta.regionout.replace(":","_") : meta.chr}" } + ext.prefix = { "${meta.id}_${meta.regionout ? meta.regionout.replace(":", "_") : meta.chr}" } } withName: GLIMPSE_LIGATE { ext.prefix = { "${meta.id}_${meta.chr}_ligate" } diff --git a/subworkflows/nf-core/vcf_impute_minimac4/main.nf b/subworkflows/nf-core/vcf_impute_minimac4/main.nf index 0fcc3dd98ea1..758233dd8933 100644 --- a/subworkflows/nf-core/vcf_impute_minimac4/main.nf +++ b/subworkflows/nf-core/vcf_impute_minimac4/main.nf @@ -6,11 +6,11 @@ include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_LIGATE } from '../../../modules/nf-co workflow VCF_IMPUTE_MINIMAC4 { take: - ch_input // channel (mandatory): [ [id, chr], vcf, tbi ] - ch_panel // channel (mandatory): [ [panel, chr], vcf, tbi ] + ch_input // channel (mandatory): [ [id, chr], vcf, tbi ] + ch_panel // channel (mandatory): [ [panel, chr], vcf, tbi ] ch_posfile // channel (optional) : [ [panel, chr], sites_vcf, sites_index ] - ch_chunks // channel (optional) : [ [panel, chr], regionout ] - ch_map // channel (optional) : [ [panel, chr], map] + ch_chunks // channel (optional) : [ [panel, chr], regionout ] + ch_map // channel (optional) : [ [panel, chr], map] main: @@ -52,11 +52,9 @@ workflow VCF_IMPUTE_MINIMAC4 { .map { metaI, target_vcf, target_tbi, metaPC, ref_msav, sites_vcf, sites_index, regionout, map -> [ metaPC + metaI + ["regionout": regionout], - target_vcf, - target_tbi, + target_vcf, target_tbi, ref_msav, - sites_vcf, - sites_index, + sites_vcf, sites_index, map, regionout, ] @@ -72,7 +70,9 @@ workflow VCF_IMPUTE_MINIMAC4 { // Ligate all phased files in one and index it ligate_input = MINIMAC4_IMPUTE.out.vcf .join( - BCFTOOLS_INDEX_PHASE.out.tbi.mix(BCFTOOLS_INDEX_PHASE.out.csi) + BCFTOOLS_INDEX_PHASE.out.tbi.mix(BCFTOOLS_INDEX_PHASE.out.csi), + failOnMismatch: true, + failOnDuplicate: true, ) .map { meta, vcf, index -> def keysToKeep = meta.keySet() - ['regionout'] @@ -88,10 +88,12 @@ workflow VCF_IMPUTE_MINIMAC4 { // Join imputed and index files ch_vcf_index = GLIMPSE2_LIGATE.out.merged_variants.join( - BCFTOOLS_INDEX_LIGATE.out.tbi.mix(BCFTOOLS_INDEX_LIGATE.out.csi) + BCFTOOLS_INDEX_LIGATE.out.tbi.mix(BCFTOOLS_INDEX_LIGATE.out.csi), + failOnMismatch: true, + failOnDuplicate: true, ) emit: vcf_index = ch_vcf_index // channel: [ [id, panel, chr], vcf, index ] - versions = ch_versions // channel: [ versions.yml ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/vcf_phase_shapeit5/main.nf b/subworkflows/nf-core/vcf_phase_shapeit5/main.nf index c1303d99667c..ce8637aee05f 100644 --- a/subworkflows/nf-core/vcf_phase_shapeit5/main.nf +++ b/subworkflows/nf-core/vcf_phase_shapeit5/main.nf @@ -1,19 +1,19 @@ -include { GLIMPSE2_CHUNK } from '../../../modules/nf-core/glimpse2/chunk' -include { SHAPEIT5_PHASECOMMON } from '../../../modules/nf-core/shapeit5/phasecommon' -include { SHAPEIT5_LIGATE } from '../../../modules/nf-core/shapeit5/ligate' -include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_1 } from '../../../modules/nf-core/bcftools/index' -include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_2 } from '../../../modules/nf-core/bcftools/index' +include { GLIMPSE2_CHUNK } from '../../../modules/nf-core/glimpse2/chunk' +include { SHAPEIT5_PHASECOMMON } from '../../../modules/nf-core/shapeit5/phasecommon' +include { SHAPEIT5_LIGATE } from '../../../modules/nf-core/shapeit5/ligate' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_PHASE } from '../../../modules/nf-core/bcftools/index' +include { BCFTOOLS_INDEX as BCFTOOLS_INDEX_LIGATE } from '../../../modules/nf-core/bcftools/index' workflow VCF_PHASE_SHAPEIT5 { take: - ch_vcf // channel (mandatory) : [ [id, chr], vcf, index, pedigree, region ] - ch_chunks // channel (optional) : [ [id, chr], regionout ] - ch_ref // channel (optional) : [ [id, chr], vcf, index ] - ch_scaffold // channel (optional) : [ [id, chr], vcf, index ] - ch_map // channel (optional) : [ [id, chr], map] - chunk // val (mandatory) : boolean to activate/deactivate chunking step - chunk_model // channel (mandatory) : [ model ] + ch_vcf // channel (mandatory) : [ [id, chr], vcf, index, pedigree, region ] + ch_chunks // channel (optional) : [ [id, chr], regionout ] + ch_ref // channel (optional) : [ [id, chr], vcf, index ] + ch_scaffold // channel (optional) : [ [id, chr], vcf, index ] + ch_map // channel (optional) : [ [id, chr], map] + chunk // val (mandatory) : boolean to activate/deactivate chunking step + chunk_model // channel (mandatory) : [ model ] main: @@ -76,13 +76,12 @@ workflow VCF_PHASE_SHAPEIT5 { SHAPEIT5_PHASECOMMON (ch_phase_input) ch_versions = ch_versions.mix(SHAPEIT5_PHASECOMMON.out.versions.first()) - BCFTOOLS_INDEX_1(SHAPEIT5_PHASECOMMON.out.phased_variant) - ch_versions = ch_versions.mix(BCFTOOLS_INDEX_1.out.versions.first()) + BCFTOOLS_INDEX_PHASE(SHAPEIT5_PHASECOMMON.out.phased_variant) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_PHASE.out.versions.first()) ch_ligate_input = SHAPEIT5_PHASECOMMON.out.phased_variant .join( - BCFTOOLS_INDEX_1.out.csi - .mix(BCFTOOLS_INDEX_1.out.tbi), + BCFTOOLS_INDEX_PHASE.out.tbi.mix(BCFTOOLS_INDEX_PHASE.out.csi), failOnMismatch:true, failOnDuplicate:true ) .map{ meta, vcf, index -> @@ -94,17 +93,17 @@ workflow VCF_PHASE_SHAPEIT5 { SHAPEIT5_LIGATE(ch_ligate_input) ch_versions = ch_versions.mix(SHAPEIT5_LIGATE.out.versions.first()) - BCFTOOLS_INDEX_2(SHAPEIT5_LIGATE.out.merged_variants) - ch_versions = ch_versions.mix(BCFTOOLS_INDEX_2.out.versions.first()) + BCFTOOLS_INDEX_LIGATE(SHAPEIT5_LIGATE.out.merged_variants) + ch_versions = ch_versions.mix(BCFTOOLS_INDEX_LIGATE.out.versions.first()) ch_vcf_index = SHAPEIT5_LIGATE.out.merged_variants .join( - BCFTOOLS_INDEX_2.out.csi.mix(BCFTOOLS_INDEX_2.out.tbi), + BCFTOOLS_INDEX_LIGATE.out.tbi.mix(BCFTOOLS_INDEX_LIGATE.out.csi), failOnMismatch:true, failOnDuplicate:true ) emit: - chunks = ch_chunks // channel: [ [id, chr], regionout] - vcf_index = ch_vcf_index // channel: [ [id, chr], vcf, csi ] - versions = ch_versions // channel: [ versions.yml ] + chunks = ch_chunks // channel: [ [id, chr], regionout] + vcf_index = ch_vcf_index // channel: [ [id, chr], vcf, csi ] + versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/vcf_phase_shapeit5/tests/main.nf.test.snap b/subworkflows/nf-core/vcf_phase_shapeit5/tests/main.nf.test.snap index a385cb7ecd1d..f4e5614b0d6b 100644 --- a/subworkflows/nf-core/vcf_phase_shapeit5/tests/main.nf.test.snap +++ b/subworkflows/nf-core/vcf_phase_shapeit5/tests/main.nf.test.snap @@ -60,17 +60,17 @@ ] ], [ + "versions.yml:md5,215cf66a55581e79fb28eaf10cfa2010", "versions.yml:md5,254449d2f1f8b59fd027d7dd4a79a986", - "versions.yml:md5,7b8268b08a3d5105126bc590d3348379", - "versions.yml:md5,9109283c8ca50c507c4b77329cc0ba79", - "versions.yml:md5,e5ace4193f44f483d16d945b9eeae318" + "versions.yml:md5,54cb297b56e211ede9108417b3ed057a", + "versions.yml:md5,7b8268b08a3d5105126bc590d3348379" ] ], "meta": { "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-12-04T14:44:18.920849936" + "timestamp": "2025-12-12T18:30:15.299570431" }, "homo_sapiens - target - no error -- stub": { "content": [ @@ -95,11 +95,11 @@ ] ], "2": [ + "versions.yml:md5,215cf66a55581e79fb28eaf10cfa2010", "versions.yml:md5,254449d2f1f8b59fd027d7dd4a79a986", + "versions.yml:md5,54cb297b56e211ede9108417b3ed057a", "versions.yml:md5,714bb0db6e2d39cf0042359a64915bc6", - "versions.yml:md5,7b8268b08a3d5105126bc590d3348379", - "versions.yml:md5,9109283c8ca50c507c4b77329cc0ba79", - "versions.yml:md5,e5ace4193f44f483d16d945b9eeae318" + "versions.yml:md5,7b8268b08a3d5105126bc590d3348379" ], "chunks": [ [ @@ -121,26 +121,26 @@ ] ], "versions": [ + "versions.yml:md5,215cf66a55581e79fb28eaf10cfa2010", "versions.yml:md5,254449d2f1f8b59fd027d7dd4a79a986", + "versions.yml:md5,54cb297b56e211ede9108417b3ed057a", "versions.yml:md5,714bb0db6e2d39cf0042359a64915bc6", - "versions.yml:md5,7b8268b08a3d5105126bc590d3348379", - "versions.yml:md5,9109283c8ca50c507c4b77329cc0ba79", - "versions.yml:md5,e5ace4193f44f483d16d945b9eeae318" + "versions.yml:md5,7b8268b08a3d5105126bc590d3348379" ] }, [ + "versions.yml:md5,215cf66a55581e79fb28eaf10cfa2010", "versions.yml:md5,254449d2f1f8b59fd027d7dd4a79a986", + "versions.yml:md5,54cb297b56e211ede9108417b3ed057a", "versions.yml:md5,714bb0db6e2d39cf0042359a64915bc6", - "versions.yml:md5,7b8268b08a3d5105126bc590d3348379", - "versions.yml:md5,9109283c8ca50c507c4b77329cc0ba79", - "versions.yml:md5,e5ace4193f44f483d16d945b9eeae318" + "versions.yml:md5,7b8268b08a3d5105126bc590d3348379" ] ], "meta": { "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-12-04T14:44:31.05363112" + "timestamp": "2025-12-12T18:30:31.471379595" }, "homo_sapiens - target - no chunks, no ref, no scaffold, no map - one chromosome": { "content": [ @@ -166,17 +166,17 @@ ] ], [ + "versions.yml:md5,215cf66a55581e79fb28eaf10cfa2010", "versions.yml:md5,254449d2f1f8b59fd027d7dd4a79a986", + "versions.yml:md5,54cb297b56e211ede9108417b3ed057a", "versions.yml:md5,714bb0db6e2d39cf0042359a64915bc6", - "versions.yml:md5,7b8268b08a3d5105126bc590d3348379", - "versions.yml:md5,9109283c8ca50c507c4b77329cc0ba79", - "versions.yml:md5,e5ace4193f44f483d16d945b9eeae318" + "versions.yml:md5,7b8268b08a3d5105126bc590d3348379" ] ], "meta": { "nf-test": "0.9.3", "nextflow": "25.10.0" }, - "timestamp": "2025-12-04T14:43:58.500525154" + "timestamp": "2025-12-12T18:29:49.942165959" } } \ No newline at end of file diff --git a/subworkflows/nf-core/vcf_phase_shapeit5/tests/nextflow.config b/subworkflows/nf-core/vcf_phase_shapeit5/tests/nextflow.config index e578757ec5c1..1907408e0c22 100644 --- a/subworkflows/nf-core/vcf_phase_shapeit5/tests/nextflow.config +++ b/subworkflows/nf-core/vcf_phase_shapeit5/tests/nextflow.config @@ -5,12 +5,12 @@ process { } withName: SHAPEIT5_PHASECOMMON { - cpus = 1 // Needed to have deterministic output for testing + cpus = 1 // needed for deterministic output ext.args = "--seed 1" ext.prefix = { "${meta.id}_${meta.chr}_${meta.regionout.replace(':', '-')}.phased" } } - withName: BCFTOOLS_INDEX_1 { + withName: BCFTOOLS_INDEX_PHASE { ext.args = '--csi' } @@ -18,7 +18,7 @@ process { ext.prefix = { "${meta.id}_${meta.chr}.ligate" } } - withName: BCFTOOLS_INDEX_2 { + withName: BCFTOOLS_INDEX_LIGATE { ext.args = '--csi' } From 460be2767f7ec41ca24062fcf265b604b177bc8a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 01:08:04 +0000 Subject: [PATCH 73/83] Update Infrastructural dependencies --- .github/workflows/lint.yml | 2 +- .github/workflows/pytest-workflow.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d5dd09b83e6b..01aa0a7f3efa 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -132,7 +132,7 @@ jobs: with: python-version: "3.14" - - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5 id: cache-pip with: path: ~/.cache/pip diff --git a/.github/workflows/pytest-workflow.yml b/.github/workflows/pytest-workflow.yml index 990a6409c2a7..a54bb2cf3cac 100644 --- a/.github/workflows/pytest-workflow.yml +++ b/.github/workflows/pytest-workflow.yml @@ -236,7 +236,7 @@ jobs: with: python-version: "3.14" - - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5 id: cache-pip-pytest with: path: ~/.cache/pip @@ -297,7 +297,7 @@ jobs: - name: Upload logs on failure if: failure() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 with: name: logs-${{ matrix.profile }}-${{ steps.parsed.outputs.result }} path: | From 0b1640f41b080a88b8ab78fa4c3b4a1c327339bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Mon, 15 Dec 2025 10:19:22 +0100 Subject: [PATCH 74/83] Remove .view() (#9567) --- modules/nf-core/genmap/map/tests/main.nf.test | 2 +- modules/nf-core/glimpse2/concordance/tests/main.nf.test | 1 - subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/nf-core/genmap/map/tests/main.nf.test b/modules/nf-core/genmap/map/tests/main.nf.test index d557cd6ce89e..1bbb9fb0fd99 100644 --- a/modules/nf-core/genmap/map/tests/main.nf.test +++ b/modules/nf-core/genmap/map/tests/main.nf.test @@ -33,7 +33,7 @@ nextflow_process { } process { """ - input[0] = GENMAP_INDEX.out.index.view() + input[0] = GENMAP_INDEX.out.index input[1] = [ [id:"bed"], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/test.bed', checkIfExists:true) diff --git a/modules/nf-core/glimpse2/concordance/tests/main.nf.test b/modules/nf-core/glimpse2/concordance/tests/main.nf.test index f37c3da863f7..94ea7958ea0a 100644 --- a/modules/nf-core/glimpse2/concordance/tests/main.nf.test +++ b/modules/nf-core/glimpse2/concordance/tests/main.nf.test @@ -80,7 +80,6 @@ nextflow_process { .combine( allele_freq ) .combine( Channel.of([[]]) ) .combine( Channel.of([["chr22", "chr22"]]) ) - .view() input[0] = list_inputs input[1] = Channel.of([[id:"params"], [],"0 0.01 0.05 0.1 0.2 0.5", [], [], [], []]) diff --git a/subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf b/subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf index c6062a1033c3..42c2105f844b 100644 --- a/subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf +++ b/subworkflows/nf-core/bam_vcf_impute_glimpse2/main.nf @@ -103,13 +103,13 @@ workflow BAM_VCF_IMPUTE_GLIMPSE2 { ch_versions = ch_versions.mix(GLIMPSE2_PHASE.out.versions.first()) // Index phased file - BCFTOOLS_INDEX_PHASE(GLIMPSE2_PHASE.out.phased_variants.view()) + BCFTOOLS_INDEX_PHASE(GLIMPSE2_PHASE.out.phased_variants) ch_versions = ch_versions.mix(BCFTOOLS_INDEX_PHASE.out.versions.first()) // Ligate all phased files in one and index it ligate_input = GLIMPSE2_PHASE.out.phased_variants .join( - BCFTOOLS_INDEX_PHASE.out.tbi.mix(BCFTOOLS_INDEX_PHASE.out.csi).view(), + BCFTOOLS_INDEX_PHASE.out.tbi.mix(BCFTOOLS_INDEX_PHASE.out.csi), failOnMismatch: true, failOnDuplicate: true, ) From f12328e16b8ee02255296b841c036988c7926275 Mon Sep 17 00:00:00 2001 From: Felix Lenner <52530259+fellen31@users.noreply.github.com> Date: Mon, 15 Dec 2025 10:31:26 +0100 Subject: [PATCH 75/83] Bump strdrop to 0.3.1 (#9565) --- modules/nf-core/strdrop/build/environment.yml | 2 +- modules/nf-core/strdrop/build/main.nf | 4 +-- .../strdrop/build/tests/main.nf.test.snap | 16 +++++----- modules/nf-core/strdrop/call/environment.yml | 2 +- modules/nf-core/strdrop/call/main.nf | 4 +-- .../strdrop/call/tests/main.nf.test.snap | 32 +++++++++---------- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/modules/nf-core/strdrop/build/environment.yml b/modules/nf-core/strdrop/build/environment.yml index 6bb6e068535a..4f106770c1e0 100644 --- a/modules/nf-core/strdrop/build/environment.yml +++ b/modules/nf-core/strdrop/build/environment.yml @@ -7,4 +7,4 @@ dependencies: - conda-forge::pip=25.3 - conda-forge::python=3.14.1 - pip: - - strdrop==0.3 + - strdrop==0.3.1 diff --git a/modules/nf-core/strdrop/build/main.nf b/modules/nf-core/strdrop/build/main.nf index 61f00927be46..85a62eed5b6f 100644 --- a/modules/nf-core/strdrop/build/main.nf +++ b/modules/nf-core/strdrop/build/main.nf @@ -4,8 +4,8 @@ process STRDROP_BUILD { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/4f/4fc3114f6d67fadb826981d29ae67f8564ee81283184893c2db677d919b5b32d/data': - 'community.wave.seqera.io/library/pip_strdrop:df8d5dc993ea6848' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f8/f860e6cdc0d4222f89145d5e5f6aba15368eefc50b65bc78890613d976344a7f/data': + 'community.wave.seqera.io/library/pip_strdrop:b1aa6c1a4a3357f2' }" input: tuple val(meta), path(training_set, stageAs: 'input/*') diff --git a/modules/nf-core/strdrop/build/tests/main.nf.test.snap b/modules/nf-core/strdrop/build/tests/main.nf.test.snap index b53395fc369e..3867589061d5 100644 --- a/modules/nf-core/strdrop/build/tests/main.nf.test.snap +++ b/modules/nf-core/strdrop/build/tests/main.nf.test.snap @@ -14,7 +14,7 @@ [ "STRDROP_BUILD", "strdrop", - "0.3" + "0.3.1" ] ], "json": [ @@ -29,7 +29,7 @@ [ "STRDROP_BUILD", "strdrop", - "0.3" + "0.3.1" ] ] }, @@ -38,7 +38,7 @@ [ "STRDROP_BUILD", "strdrop", - "0.3" + "0.3.1" ] ] } @@ -47,7 +47,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-06T11:11:57.601817569" + "timestamp": "2025-12-12T17:10:41.144598065" }, "test-stub": { "content": [ @@ -64,7 +64,7 @@ [ "STRDROP_BUILD", "strdrop", - "0.3" + "0.3.1" ] ], "json": [ @@ -79,7 +79,7 @@ [ "STRDROP_BUILD", "strdrop", - "0.3" + "0.3.1" ] ] }, @@ -88,7 +88,7 @@ [ "STRDROP_BUILD", "strdrop", - "0.3" + "0.3.1" ] ] } @@ -97,6 +97,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-06T11:12:03.26800462" + "timestamp": "2025-12-12T17:10:46.632795677" } } \ No newline at end of file diff --git a/modules/nf-core/strdrop/call/environment.yml b/modules/nf-core/strdrop/call/environment.yml index 6bb6e068535a..4f106770c1e0 100644 --- a/modules/nf-core/strdrop/call/environment.yml +++ b/modules/nf-core/strdrop/call/environment.yml @@ -7,4 +7,4 @@ dependencies: - conda-forge::pip=25.3 - conda-forge::python=3.14.1 - pip: - - strdrop==0.3 + - strdrop==0.3.1 diff --git a/modules/nf-core/strdrop/call/main.nf b/modules/nf-core/strdrop/call/main.nf index 2eafb6e82c54..86d51373d402 100644 --- a/modules/nf-core/strdrop/call/main.nf +++ b/modules/nf-core/strdrop/call/main.nf @@ -4,8 +4,8 @@ process STRDROP_CALL { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/4f/4fc3114f6d67fadb826981d29ae67f8564ee81283184893c2db677d919b5b32d/data': - 'community.wave.seqera.io/library/pip_strdrop:df8d5dc993ea6848' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/f8/f860e6cdc0d4222f89145d5e5f6aba15368eefc50b65bc78890613d976344a7f/data': + 'community.wave.seqera.io/library/pip_strdrop:b1aa6c1a4a3357f2' }" input: tuple val(meta), path(vcf) diff --git a/modules/nf-core/strdrop/call/tests/main.nf.test.snap b/modules/nf-core/strdrop/call/tests/main.nf.test.snap index 12d5982fb3ff..879afd789f1c 100644 --- a/modules/nf-core/strdrop/call/tests/main.nf.test.snap +++ b/modules/nf-core/strdrop/call/tests/main.nf.test.snap @@ -14,7 +14,7 @@ [ "STRDROP_CALL", "strdrop", - "0.3" + "0.3.1" ] ], "vcf": [ @@ -29,7 +29,7 @@ [ "STRDROP_CALL", "strdrop", - "0.3" + "0.3.1" ] ] } @@ -38,7 +38,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-10T09:27:39.835472209" + "timestamp": "2025-12-12T17:11:18.368359431" }, "vcf-input": { "content": [ @@ -48,14 +48,14 @@ { "id": "input" }, - "input.vcf.gz:md5,cc4a260ddb9e6b0fe5b481d478b27bf9" + "input.vcf.gz:md5,17c80c45e5dfdc218e68e87166bfa40b" ] ], "1": [ [ "STRDROP_CALL", "strdrop", - "0.3" + "0.3.1" ] ], "vcf": [ @@ -63,14 +63,14 @@ { "id": "input" }, - "input.vcf.gz:md5,cc4a260ddb9e6b0fe5b481d478b27bf9" + "input.vcf.gz:md5,17c80c45e5dfdc218e68e87166bfa40b" ] ], "versions_strdrop": [ [ "STRDROP_CALL", "strdrop", - "0.3" + "0.3.1" ] ] } @@ -79,7 +79,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-10T13:28:07.339844531" + "timestamp": "2025-12-12T17:11:00.099682934" }, "json-input": { "content": [ @@ -89,14 +89,14 @@ { "id": "input" }, - "input.vcf.gz:md5,cc4a260ddb9e6b0fe5b481d478b27bf9" + "input.vcf.gz:md5,17c80c45e5dfdc218e68e87166bfa40b" ] ], "1": [ [ "STRDROP_CALL", "strdrop", - "0.3" + "0.3.1" ] ], "vcf": [ @@ -104,14 +104,14 @@ { "id": "input" }, - "input.vcf.gz:md5,cc4a260ddb9e6b0fe5b481d478b27bf9" + "input.vcf.gz:md5,17c80c45e5dfdc218e68e87166bfa40b" ] ], "versions_strdrop": [ [ "STRDROP_CALL", "strdrop", - "0.3" + "0.3.1" ] ] } @@ -120,7 +120,7 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-10T13:28:01.066159827" + "timestamp": "2025-12-12T17:10:53.725030573" }, "json-input-stub": { "content": [ @@ -137,7 +137,7 @@ [ "STRDROP_CALL", "strdrop", - "0.3" + "0.3.1" ] ], "vcf": [ @@ -152,7 +152,7 @@ [ "STRDROP_CALL", "strdrop", - "0.3" + "0.3.1" ] ] } @@ -161,6 +161,6 @@ "nf-test": "0.9.2", "nextflow": "25.04.6" }, - "timestamp": "2025-12-10T09:27:33.984895465" + "timestamp": "2025-12-12T17:11:12.741135127" } } \ No newline at end of file From 2ed958f299c67b8e4d2c73a6be49ea401b60037b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Mon, 15 Dec 2025 10:44:03 +0100 Subject: [PATCH 76/83] Remove unecessary tags (#9568) * Remove .view() * Remove unecessary tags --- .../nf-core/bam_impute_quilt/tests/nextflow.config | 3 --- .../bam_vcf_impute_glimpse2/tests/nextflow.config | 12 ------------ 2 files changed, 15 deletions(-) diff --git a/subworkflows/nf-core/bam_impute_quilt/tests/nextflow.config b/subworkflows/nf-core/bam_impute_quilt/tests/nextflow.config index 7ab7994735f9..b074c3b5a26b 100644 --- a/subworkflows/nf-core/bam_impute_quilt/tests/nextflow.config +++ b/subworkflows/nf-core/bam_impute_quilt/tests/nextflow.config @@ -3,17 +3,14 @@ process { cpus = 1 // needed for deterministic output ext.args = { "${params.quilt_args}" } ext.prefix = { "${meta.id}_${meta.chr}_${meta.regionout}.quilt" } - tag = { "${meta.id} ${meta.chr} ${meta.regionout}" } } withName: GLIMPSE2_LIGATE { ext.prefix = { "${meta.id}_${meta.chr}.ligate" } - tag = { "${meta.id} ${meta.chr}" } } withName: BCFTOOLS_INDEX { ext.args = '--csi' - tag = { "${meta.id} ${meta.chr}" } publishDir = [enabled: false] } } diff --git a/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/nextflow.config b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/nextflow.config index 7aea8a877175..8ed0fd672ab7 100644 --- a/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/nextflow.config +++ b/subworkflows/nf-core/bam_vcf_impute_glimpse2/tests/nextflow.config @@ -1,7 +1,6 @@ process { withName: GLIMPSE2_CHUNK { ext.prefix = { "${meta.panel}_${meta.chr}" } - tag = { "${meta.panel} ${meta.chr}}" } ext.args = [ "--window-mb 0.01", "--window-cm 0.01", @@ -15,27 +14,16 @@ process { withName: GLIMPSE2_SPLITREFERENCE { ext.prefix = { "${meta.panel}_${meta.chr}_${meta.regionout}" } - tag = { "${meta.panel} ${meta.chr} ${meta.regionout}" } ext.args = "--seed 1" } withName: GLIMPSE2_PHASE { ext.prefix = { "${meta.id}_${meta.chr}_${meta.regionout}" } - tag = { "${meta.id} ${meta.chr} ${meta.regionout}" } cpus = 1 // needed for deterministic output ext.args = "--keep-monomorphic-ref-sites --seed 1" } - withName: BCFTOOLS_INDEX_PHASE { - tag = { "${meta.id} ${meta.chr} ${meta.regionout}" } - } - withName: GLIMPSE2_LIGATE { ext.prefix = { "${meta.id}_${meta.chr}" } - tag = { "${meta.id} ${meta.chr}" } - } - - withName: BCFTOOLS_INDEX_LIGATE { - tag = { "${meta.id} ${meta.chr}" } } } From 6546c997b3376eb7db04b03190e38b48234ba79e Mon Sep 17 00:00:00 2001 From: Evangelos Karatzas <32259775+vagkaratzas@users.noreply.github.com> Date: Mon, 15 Dec 2025 16:03:49 +0000 Subject: [PATCH 77/83] Update trimgalore (#9570) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * testing solo trim-galore container, without adding extra cutadapt and pigz * Syntax updates and topic version for manta modules (#9556) * update manta germline * topics convertinversion * topics convertinversion * topics manta/somatic * topics manta/tumoronly * Syntax updates and topics of jasminesv (#9554) syntax updates and topics of jasminesv * Update `Modkit pileup` (#9553) * update yaml * update main.nf * modified test runs * update bedmethyltobigwig tests * update main * update snapshot * fix linting * update snapshots * remove config * update module_args * [automated] Fix linting with Prettier * changed name * update main --------- Co-authored-by: ra25wog Co-authored-by: nf-core-bot * Standarize and alignment for all imputation and alignment modules (#9566) * Standarize and alignment * Fix glimpse2 sbwf test * Fix test * Add comment * Update snapshot --------- Co-authored-by: LouisLeNezet * Update Infrastructural dependencies * Remove .view() (#9567) * Bump strdrop to 0.3.1 (#9565) * Remove unecessary tags (#9568) * Remove .view() * Remove unecessary tags * latest container, with cutadapt 5.2 * new output syntax, nf-tests updated, meta updated * meta yml lint fixed * trying to fix lint * lint fix with nf-core tools 3.6.0dev * removing TRIMGALORE versions output from the FASTQ_FASTQC_UMITOOLS_TRIMGALORE subworkflow --------- Co-authored-by: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> Co-authored-by: Jinn <155078830+jkh00@users.noreply.github.com> Co-authored-by: ra25wog Co-authored-by: nf-core-bot Co-authored-by: Louis Le Nézet <58640615+LouisLeNezet@users.noreply.github.com> Co-authored-by: LouisLeNezet Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Felix Lenner <52530259+fellen31@users.noreply.github.com> --- modules/nf-core/trimgalore/environment.yml | 2 - modules/nf-core/trimgalore/main.nf | 37 +- modules/nf-core/trimgalore/meta.yml | 90 ++- modules/nf-core/trimgalore/tests/main.nf.test | 162 ++--- .../trimgalore/tests/main.nf.test.snap | 609 ++++++++++++------ .../fastq_fastqc_umitools_trimgalore/main.nf | 1 - .../tests/main.nf.test.snap | 48 +- 7 files changed, 567 insertions(+), 382 deletions(-) diff --git a/modules/nf-core/trimgalore/environment.yml b/modules/nf-core/trimgalore/environment.yml index 568b9e72efad..60b33ef21074 100644 --- a/modules/nf-core/trimgalore/environment.yml +++ b/modules/nf-core/trimgalore/environment.yml @@ -4,6 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::cutadapt=4.9 - bioconda::trim-galore=0.6.10 - - conda-forge::pigz=2.8 diff --git a/modules/nf-core/trimgalore/main.nf b/modules/nf-core/trimgalore/main.nf index 5fe53669f766..7372e720bda6 100644 --- a/modules/nf-core/trimgalore/main.nf +++ b/modules/nf-core/trimgalore/main.nf @@ -3,20 +3,20 @@ process TRIMGALORE { label 'process_high' conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container - ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/9b/9becad054093ad4083a961d12733f2a742e11728fe9aa815d678b882b3ede520/data' - : 'community.wave.seqera.io/library/cutadapt_trim-galore_pigz:a98edd405b34582d'}" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/trim-galore:0.6.10--hdfd78af_2' : + 'biocontainers/trim-galore:0.6.10--hdfd78af_2'}" input: tuple val(meta), path(reads) output: tuple val(meta), path("*{3prime,5prime,trimmed,val}{,_1,_2}.fq.gz"), emit: reads - tuple val(meta), path("*report.txt") , emit: log, optional: true - tuple val(meta), path("*unpaired{,_1,_2}.fq.gz") , emit: unpaired, optional: true - tuple val(meta), path("*.html") , emit: html, optional: true - tuple val(meta), path("*.zip") , emit: zip, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*report.txt") , emit: log , optional: true + tuple val(meta), path("*unpaired{,_1,_2}.fq.gz") , emit: unpaired, optional: true + tuple val(meta), path("*.html") , emit: html , optional: true + tuple val(meta), path("*.zip") , emit: zip , optional: true + tuple val("${task.process}"), val("trimgalore"), eval('trim_galore --version | grep -Eo "[0-9]+(\\.[0-9]+)+"'), topic: versions, emit: versions_trimgalore when: task.ext.when == null || task.ext.when @@ -52,13 +52,6 @@ process TRIMGALORE { --cores ${cores} \\ --gzip \\ ${prefix}.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - trimgalore: \$(echo \$(trim_galore --version 2>&1) | sed 's/^.*version //; s/Last.*\$//') - cutadapt: \$(cutadapt --version) - pigz: \$( pigz --version 2>&1 | sed 's/pigz //g' ) - END_VERSIONS """ } else { @@ -72,13 +65,6 @@ process TRIMGALORE { --gzip \\ ${prefix}_1.fastq.gz \\ ${prefix}_2.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - trimgalore: \$(echo \$(trim_galore --version 2>&1) | sed 's/^.*version //; s/Last.*\$//') - cutadapt: \$(cutadapt --version) - pigz: \$( pigz --version 2>&1 | sed 's/pigz //g' ) - END_VERSIONS """ } @@ -96,12 +82,5 @@ process TRIMGALORE { } """ ${output_command} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - trimgalore: \$(echo \$(trim_galore --version 2>&1) | sed 's/^.*version //; s/Last.*\$//') - cutadapt: \$(cutadapt --version) - pigz: \$( pigz --version 2>&1 | sed 's/pigz //g' ) - END_VERSIONS """ } diff --git a/modules/nf-core/trimgalore/meta.yml b/modules/nf-core/trimgalore/meta.yml index 43ac961cb4e7..dcd9b17036e4 100644 --- a/modules/nf-core/trimgalore/meta.yml +++ b/modules/nf-core/trimgalore/meta.yml @@ -1,9 +1,11 @@ name: trimgalore -description: Trim FastQ files using Trim Galore! +description: | + A wrapper around Cutadapt and FastQC to consistently apply adapter and quality trimming to FastQ files, + with extra functionality for RRBS data keywords: - trimming - adapters - - sequencing adapters + - sequencing - fastq tools: - trimgalore: @@ -14,7 +16,8 @@ tools: homepage: https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/ documentation: https://github.com/FelixKrueger/TrimGalore/blob/master/Docs/Trim_Galore_User_Guide.md licence: ["GPL-3.0-or-later"] - identifier: "" + identifier: biotools:trim_galore + input: - - meta: type: map @@ -26,7 +29,8 @@ input: description: | List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. - ontologies: [] + ontologies: + - edam: "http://edamontology.org/format_1930" # FASTQ output: reads: - - meta: @@ -35,11 +39,12 @@ output: Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - "*{3prime,5prime,trimmed,val}{,_1,_2}.fq.gz": - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] + type: file + description: The trimmed/modified fastq reads pattern: "*{3prime,5prime,trimmed,val}{,_1,_2}.fq.gz" + ontologies: + - edam: "http://edamontology.org/format_1930" # FASTQ + - edam: http://edamontology.org/format_3989 # GZIP format log: - - meta: type: map @@ -47,11 +52,11 @@ output: Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - "*report.txt": - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - pattern: "*_{report.txt}" + type: file + description: trimgalore log file + pattern: "*report.txt" + ontologies: + - edam: "http://edamontology.org/format_2330" # Textual format unpaired: - - meta: type: map @@ -59,11 +64,12 @@ output: Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - "*unpaired{,_1,_2}.fq.gz": - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] + type: file + description: unpaired reads when --retain_unpaired flag is used pattern: "*unpaired*.fq.gz" + ontologies: + - edam: "http://edamontology.org/format_1930" # FASTQ + - edam: http://edamontology.org/format_3989 # GZIP format html: - - meta: type: map @@ -71,11 +77,11 @@ output: Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - "*.html": - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - pattern: "*_{fastqc.html}" + type: file + description: FastQC HTML report after trimming when the --fastqc flag is used + pattern: "*_fastqc.html" + ontologies: + - edam: "http://edamontology.org/format_2331" # HTML zip: - - meta: type: map @@ -83,18 +89,35 @@ output: Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - "*.zip": - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - pattern: "*_{fastqc.zip}" + type: file + description: FastQC report output zip after trimming when the --fastqc flag + is used + pattern: "*_fastqc.zip" + ontologies: + - edam: http://edamontology.org/format_3987 # ZIP format + versions_trimgalore: + - - ${task.process}: + type: string + description: The name of the process + - trimgalore: + type: string + description: The name of the tool + - trim_galore --version | grep -Eo "[0-9]+(\.[0-9]+)+": + type: eval + description: The expression to obtain the version of the tool + +topics: versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - - ${task.process}: + type: string + description: The name of the process + - trimgalore: + type: string + description: The name of the tool + - trim_galore --version | grep -Eo "[0-9]+(\.[0-9]+)+": + type: eval + description: The expression to obtain the version of the tool + authors: - "@drpatelh" - "@ewels" @@ -103,3 +126,4 @@ maintainers: - "@drpatelh" - "@ewels" - "@FelixKrueger" + - "@vagkaratzas" diff --git a/modules/nf-core/trimgalore/tests/main.nf.test b/modules/nf-core/trimgalore/tests/main.nf.test index e2f11e032bd1..ac97b087142b 100644 --- a/modules/nf-core/trimgalore/tests/main.nf.test +++ b/modules/nf-core/trimgalore/tests/main.nf.test @@ -3,81 +3,83 @@ nextflow_process { name "Test Process TRIMGALORE" script "../main.nf" process "TRIMGALORE" + tag "modules" tag "modules_nfcore" tag "trimgalore" - test("test_trimgalore_single_end") { + test("sarscov2 - fastq - single-end") { when { process { """ - input[0] = [ [ id:'test', single_end:true ], // meta map - [ file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", checkIfExists: true) ] + input[0] = [ + [ id:'test', single_end:true ], + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] ] """ } } then { - def read_lines = ["@ERR5069949.2151832 NS500628:121:HK3MMAFX2:2:21208:10793:15304/1", - "TCATAAACCAAAGCACTCACAGTGTCAACAATTTCAGCAGGACAACGCCGACAAGTTCCGAGGAACATGTCTGGACCTATAGTTTTCATAAGTCTACACACTGAATTGAAATATTCTGGTTCTAGTGTGCCCTTAGTTAGCAATGTGCGT", - "AAAAAAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEE - { assert path(process.out.reads.get(0).get(1)).linesGzip.contains(read_line) } - } - }, - { report1_lines.each { report1_line -> - { assert path(process.out.log.get(0).get(1)).getText().contains(report1_line) } - } - }, - { assert snapshot(path(process.out.versions.get(0)).yaml).match() }, + { assert snapshot( + process.out.reads, + file(process.out.log[0][1]).readLines()[0..9], // line 11 changes + file(process.out.log[0][1]).readLines()[11..59], + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } ) } } - test("test_trimgalore_single_end - stub") { - - options "-stub" + test("sarscov2 - fastq - paired-end") { when { process { """ - input[0] = [ [ id:'test', single_end:true ], // meta map - [ file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", checkIfExists: true) ] + input[0] = [ [ id:'test', single_end:false ], + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] ] """ } } then { - assertAll( + assertAll ( { assert process.success }, { assert snapshot( - process.out, - path(process.out.versions.get(0)).yaml - ).match() }, + process.out.reads[0][1][0], + process.out.reads[0][1][1], + file(process.out.log[0][1][0]).readLines()[0..9], // line 11 changes + file(process.out.log[0][1][0]).readLines()[11..58], + file(process.out.log[0][1][1]).readLines()[0..9], // line 11 changes + file(process.out.log[0][1][1]).readLines()[11..60], + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } ) } } - test("test_trimgalore_paired_end") { + test("sarscov2 - fastq - paired-end - keep-unpaired") { + + config "./nextflow.config" when { + params { + module_args = '--retain_unpaired --length 150' + } + process { """ - input[0] = [ [ id:'test', single_end:false ], // meta map + input[0] = [ [ id:'test', single_end:false ], [ - file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_2.fastq.gz", checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] ] """ @@ -85,92 +87,61 @@ nextflow_process { } then { - def read1_lines = ["@ERR5069949.2151832 NS500628:121:HK3MMAFX2:2:21208:10793:15304/1", - "TCATAAACCAAAGCACTCACAGTGTCAACAATTTCAGCAGGACAACGCCGACAAGTTCCGAGGAACATGTCTGGACCTATAGTTTTCATAAGTCTACACACTGAATTGAAATATTCTGGTTCTAGTGTGCCCTTAGTTAGCAATGTGCGT", - "AAAAAAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEE - { assert path(process.out.reads.get(0).get(1).get(0)).linesGzip.contains(read1_line) } - } - }, - { read2_lines.each { read2_line -> - { assert path(process.out.reads.get(0).get(1).get(1)).linesGzip.contains(read2_line) } - } - }, - { report1_lines.each { report1_line -> - { assert path(process.out.log.get(0).get(1).get(0)).getText().contains(report1_line) } - } - }, - { report2_lines.each { report2_line -> - { assert path(process.out.log.get(0).get(1).get(1)).getText().contains(report2_line) } - } - }, - { assert snapshot(path(process.out.versions.get(0)).yaml).match() }, + { assert snapshot( + process.out.reads[0][1][0], + process.out.reads[0][1][1], + process.out.unpaired[0][1][0], + process.out.unpaired[0][1][1], + file(process.out.log[0][1][0]).readLines()[0..9], // line 11 changes + file(process.out.log[0][1][0]).readLines()[11..59], + file(process.out.log[0][1][1]).readLines()[0..9], // line 11 changes + file(process.out.log[0][1][1]).readLines()[11..63], + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } ) } } - test("test_trimgalore_paired_end_keep_unpaired") { + test("sarscov2 - fastq - single-end - stub") { - config "./nextflow.config" + options "-stub" when { - - params { - module_args = '--retain_unpaired --length 150' - } - process { """ - input[0] = [ [ id:'test', single_end:false ], // meta map - [ - file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_2.fastq.gz", checkIfExists: true) - ] + input[0] = [ + [ id:'test', single_end:true ], + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] ] """ } } then { - assertAll( + assertAll ( { assert process.success }, { assert snapshot( - path(process.out.versions.get(0)).yaml, process.out.reads, - process.out.unpaired - ).match() }, + process.out.log, + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } ) } } - test("test_trimgalore_paired_end - stub") { + test("sarscov2 - fastq - paired-end - stub") { options "-stub" when { process { """ - input[0] = [ [ id:'test', single_end:false ], // meta map + input[0] = [ [ id:'test', single_end:false ], [ - file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", checkIfExists: true), - file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_2.fastq.gz", checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] ] """ @@ -178,10 +149,13 @@ nextflow_process { } then { - assertAll( + assertAll ( { assert process.success }, - { assert snapshot(process.out).match() }, - { assert snapshot(path(process.out.versions.get(0)).yaml).match("versions") }, + { assert snapshot( + process.out.reads, + process.out.log, + process.out.findAll { key, val -> key.startsWith("versions")} + ).match() } ) } } diff --git a/modules/nf-core/trimgalore/tests/main.nf.test.snap b/modules/nf-core/trimgalore/tests/main.nf.test.snap index c454ad521f63..2fb55f2d3936 100644 --- a/modules/nf-core/trimgalore/tests/main.nf.test.snap +++ b/modules/nf-core/trimgalore/tests/main.nf.test.snap @@ -1,251 +1,468 @@ { - "test_trimgalore_single_end": { + "sarscov2 - fastq - paired-end - stub": { "content": [ - { - "TRIMGALORE": { - "trimgalore": "0.6.10", - "cutadapt": 4.9, - "pigz": 2.8 - } - } - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" - }, - "timestamp": "2025-01-06T12:25:01.330769598" - }, - "test_trimgalore_single_end - stub": { - "content": [ - { - "0": [ - [ - { - "id": "test", - "single_end": true - }, - "test_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "1": [ + [ + [ + { + "id": "test", + "single_end": false + }, [ - { - "id": "test", - "single_end": true - }, - "test.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "test_1_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] - ], - "2": [ - - ], - "3": [ - - ], - "4": [ - - ], - "5": [ - "versions.yml:md5,5928323d579768de37e83c56c821757f" - ], - "html": [ - - ], - "log": [ + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, [ - { - "id": "test", - "single_end": true - }, - "test.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "test_1.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_2.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "reads": [ + ] + ], + { + "versions_trimgalore": [ [ - { - "id": "test", - "single_end": true - }, - "test_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "TRIMGALORE", + "trimgalore", + "0.6.10" ] - ], - "unpaired": [ - - ], - "versions": [ - "versions.yml:md5,5928323d579768de37e83c56c821757f" - ], - "zip": [ - ] - }, - { - "TRIMGALORE": { - "trimgalore": "0.6.10", - "cutadapt": 4.9, - "pigz": 2.8 - } } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-01-06T12:25:15.582246999" + "timestamp": "2025-12-15T14:40:14.896140126" }, - "test_trimgalore_paired_end - stub": { + "sarscov2 - fastq - paired-end - keep-unpaired": { "content": [ + "test_1_val_1.fq.gz:md5,75413e85910bbc2e1556e12f6479f935", + "test_2_val_2.fq.gz:md5,d3c588c12646ebd36a0812fe02d0bda6", + "test_1_unpaired_1.fq.gz:md5,17e0e878f6d0e93b9008a05f128660b6", + "test_2_unpaired_2.fq.gz:md5,b09a064368a867e099e66df5ef69b044", + [ + "", + "SUMMARISING RUN PARAMETERS", + "==========================", + "Input filename: test_1.fastq.gz", + "Trimming mode: paired-end", + "Trim Galore version: 0.6.10", + "Cutadapt version: 5.2", + "Number of cores used for trimming: 1", + "Quality Phred score cutoff: 20", + "Quality encoding type selected: ASCII+33" + ], + [ + "Defaulting to Illumina universal adapter ( AGATCGGAAGAGC ). Specify -a SEQUENCE to avoid this behavior).", + "Adapter sequence: 'AGATCGGAAGAGC' (Illumina TruSeq, Sanger iPCR; default (inconclusive auto-detection))", + "Maximum trimming error rate: 0.1 (default)", + "Minimum required adapter overlap (stringency): 1 bp", + "Minimum required sequence length for both reads before a sequence pair gets removed: 150 bp", + "Length cut-off for read 1: 35 bp (default)", + "Length cut-off for read 2: 35 bp (default)", + "Output file will be GZIP compressed", + "", + "", + "This is cutadapt 5.2 with Python 3.12.12", + "Command line parameters: -j 1 -e 0.1 -q 20 -O 1 -a AGATCGGAAGAGC test_1.fastq.gz", + "Processing single-end reads on 1 core ...", + "", + "=== Summary ===", + "", + "Total reads processed: 100", + "Reads with adapters: 31 (31.0%)", + "Reads written (passing filters): 100 (100.0%)", + "", + "Total basepairs processed: 13,897 bp", + "Quality-trimmed: 0 bp (0.0%)", + "Total written (filtered): 13,851 bp (99.7%)", + "", + "=== Adapter 1 ===", + "", + "Sequence: AGATCGGAAGAGC; Type: regular 3'; Length: 13; Trimmed: 31 times", + "", + "Minimum overlap: 1", + "No. of allowed errors:", + "1-9 bp: 0; 10-13 bp: 1", + "", + "Bases preceding removed adapters:", + " A: 35.5%", + " C: 25.8%", + " G: 9.7%", + " T: 29.0%", + " none/other: 0.0%", + "", + "Overview of removed sequences", + "length\tcount\texpect\tmax.err\terror counts", + "1\t19\t25.0\t0\t19", + "2\t10\t6.2\t0\t10", + "3\t1\t1.6\t0\t1", + "4\t1\t0.4\t0\t1", + "", + "RUN STATISTICS FOR INPUT FILE: test_1.fastq.gz", + "=============================================", + "100 sequences processed in total" + ], + [ + "", + "SUMMARISING RUN PARAMETERS", + "==========================", + "Input filename: test_2.fastq.gz", + "Trimming mode: paired-end", + "Trim Galore version: 0.6.10", + "Cutadapt version: 5.2", + "Number of cores used for trimming: 1", + "Quality Phred score cutoff: 20", + "Quality encoding type selected: ASCII+33" + ], + [ + "Defaulting to Illumina universal adapter ( AGATCGGAAGAGC ). Specify -a SEQUENCE to avoid this behavior).", + "Adapter sequence: 'AGATCGGAAGAGC' (Illumina TruSeq, Sanger iPCR; default (inconclusive auto-detection))", + "Maximum trimming error rate: 0.1 (default)", + "Minimum required adapter overlap (stringency): 1 bp", + "Minimum required sequence length for both reads before a sequence pair gets removed: 150 bp", + "Length cut-off for read 1: 35 bp (default)", + "Length cut-off for read 2: 35 bp (default)", + "Output file will be GZIP compressed", + "", + "", + "This is cutadapt 5.2 with Python 3.12.12", + "Command line parameters: -j 1 -e 0.1 -q 20 -O 1 -a AGATCGGAAGAGC test_2.fastq.gz", + "Processing single-end reads on 1 core ...", + "", + "=== Summary ===", + "", + "Total reads processed: 100", + "Reads with adapters: 40 (40.0%)", + "Reads written (passing filters): 100 (100.0%)", + "", + "Total basepairs processed: 13,748 bp", + "Quality-trimmed: 0 bp (0.0%)", + "Total written (filtered): 13,693 bp (99.6%)", + "", + "=== Adapter 1 ===", + "", + "Sequence: AGATCGGAAGAGC; Type: regular 3'; Length: 13; Trimmed: 40 times", + "", + "Minimum overlap: 1", + "No. of allowed errors:", + "1-9 bp: 0; 10-13 bp: 1", + "", + "Bases preceding removed adapters:", + " A: 35.0%", + " C: 25.0%", + " G: 5.0%", + " T: 35.0%", + " none/other: 0.0%", + "", + "Overview of removed sequences", + "length\tcount\texpect\tmax.err\terror counts", + "1\t28\t25.0\t0\t28", + "2\t10\t6.2\t0\t10", + "3\t1\t1.6\t0\t1", + "4\t1\t0.4\t0\t1", + "", + "RUN STATISTICS FOR INPUT FILE: test_2.fastq.gz", + "=============================================", + "100 sequences processed in total", + "", + "Total number of sequences analysed for the sequence pair length validation: 100", + "", + "Number of sequence pairs removed because at least one read was shorter than the length cutoff (150 bp): 81 (81.00%)" + ], { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - [ - "test_1_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ] - ], - "1": [ - [ - { - "id": "test", - "single_end": false - }, - [ - "test_1.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "test_2.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "2": [ - - ], - "3": [ - - ], - "4": [ - - ], - "5": [ - "versions.yml:md5,5928323d579768de37e83c56c821757f" - ], - "html": [ - - ], - "log": [ - [ - { - "id": "test", - "single_end": false - }, - [ - "test_1.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e", - "test_2.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ] - ], - "reads": [ + "versions_trimgalore": [ [ - { - "id": "test", - "single_end": false - }, - [ - "test_1_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] + "TRIMGALORE", + "trimgalore", + "0.6.10" ] - ], - "unpaired": [ - - ], - "versions": [ - "versions.yml:md5,5928323d579768de37e83c56c821757f" - ], - "zip": [ - ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-01-06T12:26:05.201562315" + "timestamp": "2025-12-15T14:39:53.811844594" }, - "versions": { + "sarscov2 - fastq - single-end - stub": { "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test_trimmed.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], { - "TRIMGALORE": { - "trimgalore": "0.6.10", - "cutadapt": 4.9, - "pigz": 2.8 - } + "versions_trimgalore": [ + [ + "TRIMGALORE", + "trimgalore", + "0.6.10" + ] + ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-01-06T12:26:05.229598492" + "timestamp": "2025-12-15T14:40:03.991561892" }, - "test_trimgalore_paired_end": { + "sarscov2 - fastq - paired-end": { "content": [ + "test_1_val_1.fq.gz:md5,566d44cca0d22c522d6cf0e50c7165dc", + "test_2_val_2.fq.gz:md5,3c023e8e890b897821df3dc98f48c2b3", + [ + "", + "SUMMARISING RUN PARAMETERS", + "==========================", + "Input filename: test_1.fastq.gz", + "Trimming mode: paired-end", + "Trim Galore version: 0.6.10", + "Cutadapt version: 5.2", + "Number of cores used for trimming: 1", + "Quality Phred score cutoff: 20", + "Quality encoding type selected: ASCII+33" + ], + [ + "Defaulting to Illumina universal adapter ( AGATCGGAAGAGC ). Specify -a SEQUENCE to avoid this behavior).", + "Adapter sequence: 'AGATCGGAAGAGC' (Illumina TruSeq, Sanger iPCR; default (inconclusive auto-detection))", + "Maximum trimming error rate: 0.1 (default)", + "Minimum required adapter overlap (stringency): 1 bp", + "Minimum required sequence length for both reads before a sequence pair gets removed: 20 bp", + "Output file will be GZIP compressed", + "", + "", + "This is cutadapt 5.2 with Python 3.12.12", + "Command line parameters: -j 1 -e 0.1 -q 20 -O 1 -a AGATCGGAAGAGC test_1.fastq.gz", + "Processing single-end reads on 1 core ...", + "", + "=== Summary ===", + "", + "Total reads processed: 100", + "Reads with adapters: 31 (31.0%)", + "Reads written (passing filters): 100 (100.0%)", + "", + "Total basepairs processed: 13,897 bp", + "Quality-trimmed: 0 bp (0.0%)", + "Total written (filtered): 13,851 bp (99.7%)", + "", + "=== Adapter 1 ===", + "", + "Sequence: AGATCGGAAGAGC; Type: regular 3'; Length: 13; Trimmed: 31 times", + "", + "Minimum overlap: 1", + "No. of allowed errors:", + "1-9 bp: 0; 10-13 bp: 1", + "", + "Bases preceding removed adapters:", + " A: 35.5%", + " C: 25.8%", + " G: 9.7%", + " T: 29.0%", + " none/other: 0.0%", + "", + "Overview of removed sequences", + "length\tcount\texpect\tmax.err\terror counts", + "1\t19\t25.0\t0\t19", + "2\t10\t6.2\t0\t10", + "3\t1\t1.6\t0\t1", + "4\t1\t0.4\t0\t1", + "", + "RUN STATISTICS FOR INPUT FILE: test_1.fastq.gz", + "=============================================", + "100 sequences processed in total", + "" + ], + [ + "", + "SUMMARISING RUN PARAMETERS", + "==========================", + "Input filename: test_2.fastq.gz", + "Trimming mode: paired-end", + "Trim Galore version: 0.6.10", + "Cutadapt version: 5.2", + "Number of cores used for trimming: 1", + "Quality Phred score cutoff: 20", + "Quality encoding type selected: ASCII+33" + ], + [ + "Defaulting to Illumina universal adapter ( AGATCGGAAGAGC ). Specify -a SEQUENCE to avoid this behavior).", + "Adapter sequence: 'AGATCGGAAGAGC' (Illumina TruSeq, Sanger iPCR; default (inconclusive auto-detection))", + "Maximum trimming error rate: 0.1 (default)", + "Minimum required adapter overlap (stringency): 1 bp", + "Minimum required sequence length for both reads before a sequence pair gets removed: 20 bp", + "Output file will be GZIP compressed", + "", + "", + "This is cutadapt 5.2 with Python 3.12.12", + "Command line parameters: -j 1 -e 0.1 -q 20 -O 1 -a AGATCGGAAGAGC test_2.fastq.gz", + "Processing single-end reads on 1 core ...", + "", + "=== Summary ===", + "", + "Total reads processed: 100", + "Reads with adapters: 40 (40.0%)", + "Reads written (passing filters): 100 (100.0%)", + "", + "Total basepairs processed: 13,748 bp", + "Quality-trimmed: 0 bp (0.0%)", + "Total written (filtered): 13,693 bp (99.6%)", + "", + "=== Adapter 1 ===", + "", + "Sequence: AGATCGGAAGAGC; Type: regular 3'; Length: 13; Trimmed: 40 times", + "", + "Minimum overlap: 1", + "No. of allowed errors:", + "1-9 bp: 0; 10-13 bp: 1", + "", + "Bases preceding removed adapters:", + " A: 35.0%", + " C: 25.0%", + " G: 5.0%", + " T: 35.0%", + " none/other: 0.0%", + "", + "Overview of removed sequences", + "length\tcount\texpect\tmax.err\terror counts", + "1\t28\t25.0\t0\t28", + "2\t10\t6.2\t0\t10", + "3\t1\t1.6\t0\t1", + "4\t1\t0.4\t0\t1", + "", + "RUN STATISTICS FOR INPUT FILE: test_2.fastq.gz", + "=============================================", + "100 sequences processed in total", + "", + "Total number of sequences analysed for the sequence pair length validation: 100", + "" + ], { - "TRIMGALORE": { - "trimgalore": "0.6.10", - "cutadapt": 4.9, - "pigz": 2.8 - } + "versions_trimgalore": [ + [ + "TRIMGALORE", + "trimgalore", + "0.6.10" + ] + ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-01-06T12:25:33.510924538" + "timestamp": "2025-12-15T14:39:43.937555685" }, - "test_trimgalore_paired_end_keep_unpaired": { + "sarscov2 - fastq - single-end": { "content": [ - { - "TRIMGALORE": { - "trimgalore": "0.6.10", - "cutadapt": 4.9, - "pigz": 2.8 - } - }, [ [ { "id": "test", - "single_end": false + "single_end": true }, - [ - "test_1_val_1.fq.gz:md5,75413e85910bbc2e1556e12f6479f935", - "test_2_val_2.fq.gz:md5,d3c588c12646ebd36a0812fe02d0bda6" - ] + "test_trimmed.fq.gz:md5,566d44cca0d22c522d6cf0e50c7165dc" ] ], [ - [ - { - "id": "test", - "single_end": false - }, + "", + "SUMMARISING RUN PARAMETERS", + "==========================", + "Input filename: test.fastq.gz", + "Trimming mode: single-end", + "Trim Galore version: 0.6.10", + "Cutadapt version: 5.2", + "Number of cores used for trimming: 1", + "Quality Phred score cutoff: 20", + "Quality encoding type selected: ASCII+33" + ], + [ + "Defaulting to Illumina universal adapter ( AGATCGGAAGAGC ). Specify -a SEQUENCE to avoid this behavior).", + "Adapter sequence: 'AGATCGGAAGAGC' (Illumina TruSeq, Sanger iPCR; default (inconclusive auto-detection))", + "Maximum trimming error rate: 0.1 (default)", + "Minimum required adapter overlap (stringency): 1 bp", + "Minimum required sequence length before a sequence gets removed: 20 bp", + "Output file will be GZIP compressed", + "", + "", + "This is cutadapt 5.2 with Python 3.12.12", + "Command line parameters: -j 1 -e 0.1 -q 20 -O 1 -a AGATCGGAAGAGC test.fastq.gz", + "Processing single-end reads on 1 core ...", + "", + "=== Summary ===", + "", + "Total reads processed: 100", + "Reads with adapters: 31 (31.0%)", + "Reads written (passing filters): 100 (100.0%)", + "", + "Total basepairs processed: 13,897 bp", + "Quality-trimmed: 0 bp (0.0%)", + "Total written (filtered): 13,851 bp (99.7%)", + "", + "=== Adapter 1 ===", + "", + "Sequence: AGATCGGAAGAGC; Type: regular 3'; Length: 13; Trimmed: 31 times", + "", + "Minimum overlap: 1", + "No. of allowed errors:", + "1-9 bp: 0; 10-13 bp: 1", + "", + "Bases preceding removed adapters:", + " A: 35.5%", + " C: 25.8%", + " G: 9.7%", + " T: 29.0%", + " none/other: 0.0%", + "", + "Overview of removed sequences", + "length\tcount\texpect\tmax.err\terror counts", + "1\t19\t25.0\t0\t19", + "2\t10\t6.2\t0\t10", + "3\t1\t1.6\t0\t1", + "4\t1\t0.4\t0\t1", + "", + "RUN STATISTICS FOR INPUT FILE: test.fastq.gz", + "=============================================", + "100 sequences processed in total", + "Sequences removed because they became shorter than the length cutoff of 20 bp:\t0 (0.0%)", + "" + ], + { + "versions_trimgalore": [ [ - "test_1_unpaired_1.fq.gz:md5,17e0e878f6d0e93b9008a05f128660b6", - "test_2_unpaired_2.fq.gz:md5,b09a064368a867e099e66df5ef69b044" + "TRIMGALORE", + "trimgalore", + "0.6.10" ] ] - ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.3" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-01-06T12:25:46.461002981" + "timestamp": "2025-12-15T14:39:33.985021562" } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf b/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf index 2bde86b9bb5d..f9828ae80814 100644 --- a/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf +++ b/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf @@ -75,7 +75,6 @@ workflow FASTQ_FASTQC_UMITOOLS_TRIMGALORE { trim_html = TRIMGALORE.out.html trim_zip = TRIMGALORE.out.zip trim_log = TRIMGALORE.out.log - ch_versions = ch_versions.mix(TRIMGALORE.out.versions.first()) // // Filter FastQ files based on minimum trimmed read count after adapter trimming diff --git a/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/tests/main.nf.test.snap index 8964c78d3050..00a39ad2969a 100644 --- a/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/tests/main.nf.test.snap @@ -60,7 +60,6 @@ ] ], "9": [ - "versions.yml:md5,6bcfe4e08308ca239c09bbd6cbcef429", "versions.yml:md5,dcab4a385c50da681b3de6758eb2b6a3" ], "fastqc_html": [ @@ -121,16 +120,15 @@ ] ], "versions": [ - "versions.yml:md5,6bcfe4e08308ca239c09bbd6cbcef429", "versions.yml:md5,dcab4a385c50da681b3de6758eb2b6a3" ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-10-28T12:27:03.8819" + "timestamp": "2025-12-15T15:28:25.221583852" }, "test paired end read without UMI - stub": { "content": [ @@ -190,7 +188,7 @@ ] ], "9": [ - "versions.yml:md5,6bcfe4e08308ca239c09bbd6cbcef429" + ], "fastqc_html": [ [ @@ -247,15 +245,15 @@ ], "versions": [ - "versions.yml:md5,6bcfe4e08308ca239c09bbd6cbcef429" + ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-10-28T12:27:10.975876" + "timestamp": "2025-12-15T15:28:35.359974345" }, "test paired end read without UMI": { "content": [ @@ -284,14 +282,14 @@ ], [ - "versions.yml:md5,6bcfe4e08308ca239c09bbd6cbcef429" + ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-10-28T12:26:38.03402" + "timestamp": "2025-12-15T15:27:53.738662501" }, "test single end read with UMI": { "content": [ @@ -317,15 +315,14 @@ ], [ - "versions.yml:md5,6bcfe4e08308ca239c09bbd6cbcef429", "versions.yml:md5,dcab4a385c50da681b3de6758eb2b6a3" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-10-28T12:26:10.127863" + "timestamp": "2025-12-15T15:27:29.623486754" }, "test paired end read with UMI": { "content": [ @@ -351,15 +348,14 @@ ], [ - "versions.yml:md5,6bcfe4e08308ca239c09bbd6cbcef429", "versions.yml:md5,dcab4a385c50da681b3de6758eb2b6a3" ] ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-10-28T12:26:22.604731" + "timestamp": "2025-12-15T15:27:42.00346843" }, "test skip all steps": { "content": [ @@ -440,7 +436,6 @@ ] ], "9": [ - "versions.yml:md5,6bcfe4e08308ca239c09bbd6cbcef429", "versions.yml:md5,dcab4a385c50da681b3de6758eb2b6a3" ], "fastqc_html": [ @@ -501,15 +496,14 @@ ] ], "versions": [ - "versions.yml:md5,6bcfe4e08308ca239c09bbd6cbcef429", "versions.yml:md5,dcab4a385c50da681b3de6758eb2b6a3" ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.10.0" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-10-28T12:26:52.816907" + "timestamp": "2025-12-15T15:28:12.765282278" } } \ No newline at end of file From ad92ee7ce647d752e5284cad4c5bf507ac94fd54 Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Mon, 15 Dec 2025 16:13:42 +0000 Subject: [PATCH 78/83] trimgalore output versions removed --- .../fastq_removeadapters_merge/main.nf | 1 - .../tests/main.nf.test.snap | 41 ++++--------------- 2 files changed, 9 insertions(+), 33 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index fc6e174ccf20..f11bea5f9b85 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -65,7 +65,6 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { ch_trimgalore_log = TRIMGALORE.out.log ch_trimgalore_html = TRIMGALORE.out.html ch_trimgalore_zip = TRIMGALORE.out.zip - ch_versions = ch_versions.mix(TRIMGALORE.out.versions.first()) } if (!skip_bbduk) { diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap index 1bc57e13618c..54ac2a7384aa 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap @@ -50,7 +50,6 @@ ], "11": [ - "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", "versions.yml:md5,2d5c9b99267e97292e2a581635bd72f7", "versions.yml:md5,aa418419664a944b74696ee0e9ef1c7a", "versions.yml:md5,ba074f9db361b3f8d0a8cc93c3907a91", @@ -309,7 +308,6 @@ ] ], "versions": [ - "versions.yml:md5,2646f5a30c37e118667329e29dab3c56", "versions.yml:md5,2d5c9b99267e97292e2a581635bd72f7", "versions.yml:md5,aa418419664a944b74696ee0e9ef1c7a", "versions.yml:md5,ba074f9db361b3f8d0a8cc93c3907a91", @@ -322,7 +320,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-12T14:39:53.946631816" + "timestamp": "2025-12-15T16:11:48.259971231" }, "sarscov2 - fastq - paired-end": { "content": [ @@ -344,8 +342,8 @@ ], "test_trim.log:md5,9629761761a34576b3484bf4174f681f", "test.summary:md5,9698e5e5c060bbe64588998fe35f8d71", - 60, - 63, + 59, + 62, "test.fastp.html", 51, [ @@ -362,13 +360,6 @@ "adapterremoval": "2.3.2" } }, - { - "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { - "trimgalore": "0.6.10", - "cutadapt": 4.9, - "pigz": 2.8 - } - }, { "FASTQ_REMOVEADAPTERS_MERGE:FASTP": { "fastp": "1.0.1" @@ -395,7 +386,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-12T14:42:11.204624875" + "timestamp": "2025-12-15T16:11:16.074223859" }, "sarscov2 - fastq - single-end": { "content": [ @@ -407,7 +398,7 @@ ], "test_trim.log:md5,e4c3f619e9b0e26847f8f3e3d9af319b", "test.summary:md5,24c973237557a1439c775ca19a5deaa5", - 61, + 60, "test.fastp.html", 32, [ @@ -419,13 +410,6 @@ "test_out.log" ], [ - { - "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { - "trimgalore": "0.6.10", - "cutadapt": 4.9, - "pigz": 2.8 - } - }, { "FASTQ_REMOVEADAPTERS_MERGE:FASTP": { "fastp": "1.0.1" @@ -457,7 +441,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-12T14:41:57.40696623" + "timestamp": "2025-12-15T16:11:01.68533947" }, "sarscov2 - fastq - paired-end - no-merge": { "content": [ @@ -478,8 +462,8 @@ ], "test_trim.log:md5,9629761761a34576b3484bf4174f681f", "test.summary:md5,9698e5e5c060bbe64588998fe35f8d71", - 60, - 63, + 59, + 62, "test.fastp.html", 51, [ @@ -496,13 +480,6 @@ "adapterremoval": "2.3.2" } }, - { - "FASTQ_REMOVEADAPTERS_MERGE:TRIMGALORE": { - "trimgalore": "0.6.10", - "cutadapt": 4.9, - "pigz": 2.8 - } - }, { "FASTQ_REMOVEADAPTERS_MERGE:FASTP": { "fastp": "1.0.1" @@ -529,6 +506,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-12T14:42:24.930358468" + "timestamp": "2025-12-15T16:11:29.80825695" } } \ No newline at end of file From 3ca740092bccf1815bffd6aed5875011861558a1 Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Tue, 16 Dec 2025 13:39:02 +0000 Subject: [PATCH 79/83] structure for subworkflow outputs in meta.yml file --- .../fastq_removeadapters_merge/meta.yml | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml index 1012d6ce1120..54d6f6ff89a3 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml +++ b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml @@ -78,53 +78,69 @@ input: output: - reads: type: file - description: The trimmed/modified single or paired end fastq reads + description: | + Structure: [ val(meta), path(fastq.gz) ] + The trimmed/modified single or paired end fastq reads pattern: "*.fastq.gz" - merged_reads: type: file description: | + Structure: [ val(meta), path(fastq.gz) ] The trimmed/modified fastq reads merged into a single file. Only meaningful for paired-end reads. pattern: "*.fastq.gz" - discarded_reads: type: file description: | + Structure: [ val(meta), path(fastq.gz) ] All files containing discarded reads throughout the steps. pattern: "*.fastq.gz" - trimmomatic_trim_log: type: file - description: trimmomatic log file, from the trim_log parameter + description: | + Structure: [ val(meta), path(log) ] + trimmomatic log file, from the trim_log parameter pattern: "*.log" - trimmomatic_summary: type: file - description: trimmomatic summary file of surviving and dropped reads + description: | + Structure: [ val(meta), path(summary) ] + trimmomatic summary file of surviving and dropped reads pattern: "*.summary" - trimgalore_log: type: file description: | + Structure: [ val(meta), path(txt) ] trimgalore log file pattern: "*_report.txt" - trimgalore_html: type: file description: | + Structure: [ val(meta), path(html) ] fastqc HTML output if run with the --fastqc flag. pattern: "*_fastqc.html" - trimgalore_zip: type: file description: | + Structure: [ val(meta), path(zip) ] fastqc zip output if run with the --fastqc flag. pattern: "*_fastqc.zip" - fastp_html: type: file - description: fastp results in HTML format + description: | + Structure: [ val(meta), path(html) ] + fastp results in HTML format pattern: "*.html" - fastp_log: type: file - description: fastp fastq log file + description: | + Structure: [ val(meta), path(log) ] + fastp fastq log file pattern: "*.log" - adapterremoval_paired_interleaved: type: file description: | + Structure: [ val(meta), path(fastq.gz) ] Write paired-end reads to a single file, interleaving mate 1 and mate 2 reads pattern: "*.paired.fastq.gz" - versions: From e73c143ddc055a887134ae62bc11337dd4157a40 Mon Sep 17 00:00:00 2001 From: Evangelos Karatzas <32259775+vagkaratzas@users.noreply.github.com> Date: Fri, 19 Dec 2025 08:32:28 +0000 Subject: [PATCH 80/83] Update subworkflows/nf-core/fastq_removeadapters_merge/main.nf Co-authored-by: James A. Fellows Yates --- subworkflows/nf-core/fastq_removeadapters_merge/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index f11bea5f9b85..ac6fd7c92f42 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -12,7 +12,7 @@ include { ADAPTERREMOVAL as ADAPTERREMOVAL_PE } from '../../../modules/nf-core/a workflow FASTQ_REMOVEADAPTERS_MERGE { take: - reads // channel: [ val(meta), [ reads ] ] + input_reads // channel: [ val(meta), [ reads ] ] skip_trimmomatic // boolean skip_cutadapt // boolean skip_trimgalore // boolean From 7184754a2f33a7422d1ca78c511b9929e64c1c5f Mon Sep 17 00:00:00 2001 From: Evangelos Karatzas <32259775+vagkaratzas@users.noreply.github.com> Date: Fri, 19 Dec 2025 08:32:42 +0000 Subject: [PATCH 81/83] Update subworkflows/nf-core/fastq_removeadapters_merge/main.nf Co-authored-by: James A. Fellows Yates --- subworkflows/nf-core/fastq_removeadapters_merge/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index ac6fd7c92f42..37b9d8c31e86 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -132,7 +132,7 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { } emit: - reads = ch_reads // channel: [ val(meta), [ fastq.gz ] ] + processed_reads = ch_reads // channel: [ val(meta), [ fastq.gz ] ] merged_reads = ch_merged_reads // channel: [ val(meta), [ fastq.gz ] ] discarded_reads = ch_discarded_reads // channel: [ val(meta), [ fastq.gz ] ] trimmomatic_trim_log = ch_trimmomatic_trim_log // channel: [ val(meta), [ log ] ] From 36a9fff3a3195de848be70cabf104cd5534b8445 Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Fri, 19 Dec 2025 10:27:35 +0000 Subject: [PATCH 82/83] main and meta updated with new one-tool logic --- .../fastq_removeadapters_merge/main.nf | 180 ++++++++---------- .../fastq_removeadapters_merge/meta.yml | 129 ++++--------- .../tests/main.nf.test | 110 ++++++----- 3 files changed, 173 insertions(+), 246 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf index 37b9d8c31e86..70d37e0c3b5f 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/main.nf +++ b/subworkflows/nf-core/fastq_removeadapters_merge/main.nf @@ -12,72 +12,53 @@ include { ADAPTERREMOVAL as ADAPTERREMOVAL_PE } from '../../../modules/nf-core/a workflow FASTQ_REMOVEADAPTERS_MERGE { take: - input_reads // channel: [ val(meta), [ reads ] ] - skip_trimmomatic // boolean - skip_cutadapt // boolean - skip_trimgalore // boolean - skip_bbduk // boolean - contaminants // channel: [ reads ] // fasta, adapters to remove - skip_leehom // boolean - skip_fastp // boolean - fastp_discard_trimmed_pass // boolean - fastp_save_trimmed_fail // boolean - save_merged // boolean - skip_adapterremoval // boolean - text_adapters // channel: [ txt ] // adapters to remove, in adapterremoval text format + ch_input_reads // channel: [mandatory] meta, reads + val_adapter_tool // string: [mandatory] tool_name // choose from: ["trimmomatic", "cutadapt", "trimgalore", "bbduk", "leehom", "fastp", "adapterremoval"] + ch_adapters // channel: [optional] {fasta,txt} // fasta, for bbduk or fastp, or txt, for adapterremoval + val_save_merged // boolean: [mandatory] if true, will return the merged reads instead, for fastp and adapterremoval + val_fastp_discard_trimmed_pass // boolean: [mandatory] // only for fastp + val_fastp_save_trimmed_fail // boolean: [mandatory] // only for fastp main: - ch_reads = reads - ch_merged_reads = channel.empty() - ch_discarded_reads = channel.empty() - ch_trimmomatic_trim_log = channel.empty() - ch_trimmomatic_summary = channel.empty() - ch_trimgalore_log = channel.empty() - ch_trimgalore_html = channel.empty() - ch_trimgalore_zip = channel.empty() - ch_fastp_html = channel.empty() - ch_fastp_log = channel.empty() - ch_adapterremoval_paired_interleaved = channel.empty() - ch_versions = channel.empty() - ch_multiqc_files = channel.empty() + ch_discarded_reads = channel.empty() // from trimmomatic, trimgalore, leehom, fastp, adapterremoval + ch_paired_interleaved = channel.empty() // from adapterremoval + ch_log = channel.empty() // from trimmomatic, trimgalore, fastp + ch_report = channel.empty() // from trimmomatic, trimgalore, fastp + ch_versions = channel.empty() + ch_multiqc_files = channel.empty() // from trimmomatic, cutadapt, bbduk, leehom, fastp, adapterremoval - if (!skip_trimmomatic) { - TRIMMOMATIC( ch_reads ) - ch_reads = TRIMMOMATIC.out.trimmed_reads - ch_discarded_reads = ch_discarded_reads.mix(TRIMMOMATIC.out.unpaired_reads.transpose()) // .transpose() because paired reads have 2 unpaired files in an array - ch_trimmomatic_trim_log = TRIMMOMATIC.out.trim_log - ch_trimmomatic_summary = TRIMMOMATIC.out.summary - ch_versions = ch_versions.mix(TRIMMOMATIC.out.versions.first()) - ch_multiqc_files = ch_multiqc_files.mix(TRIMMOMATIC.out.out_log) - } + if (val_adapter_tool == "trimmomatic") { + TRIMMOMATIC( ch_input_reads ) - if (!skip_cutadapt) { - CUTADAPT( ch_reads ) - ch_reads = CUTADAPT.out.reads - ch_multiqc_files = ch_multiqc_files.mix(CUTADAPT.out.log) - } + ch_processed_reads = TRIMMOMATIC.out.trimmed_reads + ch_discarded_reads = ch_discarded_reads.mix(TRIMMOMATIC.out.unpaired_reads.transpose()) // .transpose() because paired reads have 2 unpaired files in an array + ch_log = TRIMMOMATIC.out.trim_log + ch_report = TRIMMOMATIC.out.summary + ch_versions = ch_versions.mix(TRIMMOMATIC.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix(TRIMMOMATIC.out.out_log) + } else if (val_adapter_tool == "cutadapt") { + CUTADAPT( ch_input_reads ) - if (!skip_trimgalore) { - TRIMGALORE( ch_reads ) - ch_reads = TRIMGALORE.out.reads - ch_discarded_reads = ch_discarded_reads.mix(TRIMGALORE.out.unpaired) - ch_trimgalore_log = TRIMGALORE.out.log - ch_trimgalore_html = TRIMGALORE.out.html - ch_trimgalore_zip = TRIMGALORE.out.zip - } + ch_processed_reads = CUTADAPT.out.reads + ch_multiqc_files = ch_multiqc_files.mix(CUTADAPT.out.log) + } else if (val_adapter_tool == "trimgalore") { + TRIMGALORE( ch_input_reads ) - if (!skip_bbduk) { - BBMAP_BBDUK( ch_reads, contaminants ) - ch_reads = BBMAP_BBDUK.out.reads - ch_versions = ch_versions.mix(BBMAP_BBDUK.out.versions.first()) - ch_multiqc_files = ch_multiqc_files.mix(BBMAP_BBDUK.out.log) - } + ch_processed_reads = TRIMGALORE.out.reads + ch_discarded_reads = ch_discarded_reads.mix(TRIMGALORE.out.unpaired) + ch_log = TRIMGALORE.out.log + ch_report = TRIMGALORE.out.html.mix(TRIMGALORE.out.zip) + } else if (val_adapter_tool == "bbduk") { + BBMAP_BBDUK( ch_input_reads, ch_adapters ) - if (!skip_leehom) { - LEEHOM( ch_reads ) + ch_processed_reads = BBMAP_BBDUK.out.reads + ch_versions = ch_versions.mix(BBMAP_BBDUK.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix(BBMAP_BBDUK.out.log) + } else if (val_adapter_tool == "leehom") { + LEEHOM( ch_input_reads ) - ch_reads = LEEHOM.out.fq_pass + ch_processed_reads = LEEHOM.out.fq_pass .join(LEEHOM.out.unmerged_r1_fq_pass, by: 0, remainder: true) .join(LEEHOM.out.unmerged_r2_fq_pass, by: 0, remainder: true) .map { meta, single, r1, r2 -> @@ -90,59 +71,58 @@ workflow FASTQ_REMOVEADAPTERS_MERGE { ch_discarded_reads = ch_discarded_reads.mix(LEEHOM.out.fq_fail, LEEHOM.out.unmerged_r1_fq_fail, LEEHOM.out.unmerged_r2_fq_fail) ch_versions = ch_versions.mix(LEEHOM.out.versions.first()) ch_multiqc_files = ch_multiqc_files.mix(LEEHOM.out.log) - } - - if (!skip_fastp) { + } else if (val_adapter_tool == "fastp") { FASTP( - ch_reads.map { meta, files -> [ meta, files, contaminants ] }, - fastp_discard_trimmed_pass, - fastp_save_trimmed_fail, - save_merged + ch_input_reads.map { meta, files -> [ meta, files, ch_adapters ] }, + val_fastp_discard_trimmed_pass, + val_fastp_save_trimmed_fail, + val_save_merged ) - ch_reads = FASTP.out.reads - ch_merged_reads = FASTP.out.reads_merged - ch_discarded_reads = ch_discarded_reads.mix(FASTP.out.reads_fail.transpose()) // .transpose() because paired reads have 3 fail files in an array - ch_fastp_html = FASTP.out.html - ch_fastp_log = FASTP.out.log - ch_versions = ch_versions.mix(FASTP.out.versions.first()) - ch_multiqc_files = ch_multiqc_files.mix(FASTP.out.json) - } - if (!skip_adapterremoval) { - ch_adapterremoval_in = ch_reads + if (val_save_merged) { + ch_processed_reads = FASTP.out.reads_merged + } else { + ch_processed_reads = FASTP.out.reads + } + ch_discarded_reads = ch_discarded_reads.mix(FASTP.out.reads_fail.transpose()) // .transpose() because paired reads have 3 fail files in an array + ch_log = FASTP.out.log + ch_report = FASTP.out.html + ch_versions = ch_versions.mix(FASTP.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix(FASTP.out.json) + } else if (val_adapter_tool == "adapterremoval") { + ch_adapterremoval_in = ch_input_reads .branch { meta, _reads -> single: meta.single_end paired: !meta.single_end } - ADAPTERREMOVAL_SE( ch_adapterremoval_in.single, text_adapters ) - ADAPTERREMOVAL_PE( ch_adapterremoval_in.paired, text_adapters ) + ADAPTERREMOVAL_SE( ch_adapterremoval_in.single, ch_adapters ) + ADAPTERREMOVAL_PE( ch_adapterremoval_in.paired, ch_adapters ) - ch_reads = ADAPTERREMOVAL_SE.out.singles_truncated.mix(ADAPTERREMOVAL_PE.out.paired_truncated) - ch_merged_reads = ADAPTERREMOVAL_SE.out.collapsed - .mix( - ADAPTERREMOVAL_PE.out.collapsed, - ADAPTERREMOVAL_SE.out.collapsed_truncated, - ADAPTERREMOVAL_PE.out.collapsed_truncated - ) - ch_discarded_reads = ch_discarded_reads.mix(ADAPTERREMOVAL_SE.out.discarded, ADAPTERREMOVAL_PE.out.discarded) - ch_adapterremoval_paired_interleaved = ADAPTERREMOVAL_SE.out.paired_interleaved.mix(ADAPTERREMOVAL_PE.out.paired_interleaved) - ch_versions = ch_versions.mix(ADAPTERREMOVAL_SE.out.versions.first(), ADAPTERREMOVAL_PE.out.versions.first()) - ch_multiqc_files = ch_multiqc_files.mix(ADAPTERREMOVAL_PE.out.settings, ADAPTERREMOVAL_SE.out.settings) + if (val_save_merged) { + ch_processed_reads = ADAPTERREMOVAL_SE.out.collapsed + .mix( + ADAPTERREMOVAL_PE.out.collapsed, + ADAPTERREMOVAL_SE.out.collapsed_truncated, + ADAPTERREMOVAL_PE.out.collapsed_truncated + ) + } else { + ch_processed_reads = ADAPTERREMOVAL_SE.out.singles_truncated.mix(ADAPTERREMOVAL_PE.out.paired_truncated) + } + ch_discarded_reads = ch_discarded_reads.mix(ADAPTERREMOVAL_SE.out.discarded, ADAPTERREMOVAL_PE.out.discarded) + ch_paired_interleaved = ADAPTERREMOVAL_SE.out.paired_interleaved.mix(ADAPTERREMOVAL_PE.out.paired_interleaved) + ch_versions = ch_versions.mix(ADAPTERREMOVAL_SE.out.versions.first(), ADAPTERREMOVAL_PE.out.versions.first()) + ch_multiqc_files = ch_multiqc_files.mix(ADAPTERREMOVAL_PE.out.settings, ADAPTERREMOVAL_SE.out.settings) + } else { + error('Please choose one of the available adapter removal and merging tools: ["trimmomatic", "cutadapt", "trimgalore", "bbduk", "leehom", "fastp", "adapterremoval"]') } emit: - processed_reads = ch_reads // channel: [ val(meta), [ fastq.gz ] ] - merged_reads = ch_merged_reads // channel: [ val(meta), [ fastq.gz ] ] - discarded_reads = ch_discarded_reads // channel: [ val(meta), [ fastq.gz ] ] - trimmomatic_trim_log = ch_trimmomatic_trim_log // channel: [ val(meta), [ log ] ] - trimmomatic_summary = ch_trimmomatic_summary // channel: [ val(meta), [ summary ] ] - trimgalore_log = ch_trimgalore_log // channel: [ val(meta), [ txt ] ] - trimgalore_html = ch_trimgalore_html // channel: [ val(meta), [ html ] ] - trimgalore_zip = ch_trimgalore_zip // channel: [ val(meta), [ zip ] ] - fastp_html = ch_fastp_html // channel: [ val(meta), [ html ] ] - fastp_log = ch_fastp_log // channel: [ val(meta), [ log ] ] - adapterremoval_paired_interleaved = ch_adapterremoval_paired_interleaved // channel: [ val(meta), [ fastq.gz ] ] - versions = ch_versions // channel: [ versions.yml ] - multiqc_files = ch_multiqc_files + processed_reads = ch_processed_reads // channel: [ val(meta), [ fastq.gz ] ] + discarded_reads = ch_discarded_reads // channel: [ val(meta), [ fastq.gz ] ] + paired_interleaved = ch_paired_interleaved // channel: [ val(meta), [ fastq.gz ] ] + logfile = ch_log // channel: [ val(meta), [ {log,txt} ] ] + report = ch_report // channel: [ val(meta), [ {summary,html,zip} ] ] + versions = ch_versions // channel: [ versions.yml ] + multiqc_files = ch_multiqc_files } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml index 54d6f6ff89a3..2221130fdda5 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml +++ b/subworkflows/nf-core/fastq_removeadapters_merge/meta.yml @@ -16,133 +16,68 @@ components: - fastp - adapterremoval input: - - ch_reads: + - ch_input_reads: type: file description: | List of FastQ files of size 1 and 2 for single-end and paired-end data, respectively. Structure: [ val(meta), [ path(reads) ] ] - - skip_trimmomatic: - type: boolean - description: | - If true, skips the trimmomatic process. - - skip_cutadapt: - type: boolean - description: | - If true, skips the cutadapt process. - - skip_trimgalore: - type: boolean + - val_adapter_tool: + type: string description: | - If true, skips the trimgalore process. - We suggest running either cutadapt or trimgalore, - because trimgalore also runs cutadapt in the background. - - skip_bbduk: - type: boolean - description: | - If true, skips the bbmap/bbduk process. - - contaminants: + Choose one of the available adapter removal and/or merging tools + enum: ["trimmomatic", "cutadapt", "trimgalore", "bbduk", "leehom", "fastp", "adapterremoval"] + - ch_adapters: type: file description: | - Reference files used by bbmap/bbduk and/or fastp, containing adapter and/or contaminant sequences for removal - - skip_leehom: - type: boolean - description: | - If true, skips the leehom process. - - skip_fastp: + Optional reference files, containing adapter and/or contaminant sequences for removal. + In fasta format for bbmap/bbduk and fastp, or in text format for AdapterRemoval (one adapter per line). + - val_save_merged: type: boolean description: | - If true, skips the fastp process. - - fastp_discard_trimmed_pass: + Specify true to output merged reads instead + Used by fastp and adapterremoval + - val_fastp_discard_trimmed_pass: type: boolean description: | + Used only by fastp. Specify true to not write any reads that pass trimming thresholds from the fastp process. This can be used to use fastp for the output report only. - - fastp_save_trimmed_fail: + - val_fastp_save_trimmed_fail: type: boolean description: | + Used only by fastp. Specify true to save files that failed to pass fastp trimming thresholds - ending in `*.fail.fastq.gz` - - save_merged: - type: boolean - description: | - Specify true to save all merged reads to a file ending in `*.merged.fastq.gz` - Used by fastp - - skip_adapterremoval: - type: boolean - description: | - If true, skips the adapterremoval process. - - text_adapters: - type: file - description: Optional text file containing list of adapters to look for for removal - with one adapter per line. Otherwise will look for default adapters (see AdapterRemoval - man page), or can be modified to remove user-specified adapters via ext.args. output: - - reads: + - processed_reads: type: file description: | Structure: [ val(meta), path(fastq.gz) ] - The trimmed/modified single or paired end fastq reads - pattern: "*.fastq.gz" - - merged_reads: - type: file - description: | - Structure: [ val(meta), path(fastq.gz) ] - The trimmed/modified fastq reads merged into a single file. - Only meaningful for paired-end reads. + The trimmed/modified single or paired end or merged fastq reads pattern: "*.fastq.gz" - discarded_reads: type: file description: | Structure: [ val(meta), path(fastq.gz) ] - All files containing discarded reads throughout the steps. + The discarded reads pattern: "*.fastq.gz" - - trimmomatic_trim_log: - type: file - description: | - Structure: [ val(meta), path(log) ] - trimmomatic log file, from the trim_log parameter - pattern: "*.log" - - trimmomatic_summary: - type: file - description: | - Structure: [ val(meta), path(summary) ] - trimmomatic summary file of surviving and dropped reads - pattern: "*.summary" - - trimgalore_log: - type: file - description: | - Structure: [ val(meta), path(txt) ] - trimgalore log file - pattern: "*_report.txt" - - trimgalore_html: - type: file - description: | - Structure: [ val(meta), path(html) ] - fastqc HTML output if run with the --fastqc flag. - pattern: "*_fastqc.html" - - trimgalore_zip: - type: file - description: | - Structure: [ val(meta), path(zip) ] - fastqc zip output if run with the --fastqc flag. - pattern: "*_fastqc.zip" - - fastp_html: + - paired_interleaved: type: file description: | - Structure: [ val(meta), path(html) ] - fastp results in HTML format - pattern: "*.html" - - fastp_log: + Structure: [ val(meta), path(fastq.gz) ] + Adapterremoval paired-end reads in a single file, interleaving mate 1 and mate 2 reads + pattern: "*.paired.fastq.gz" + - logfile: type: file description: | - Structure: [ val(meta), path(log) ] - fastp fastq log file - pattern: "*.log" - - adapterremoval_paired_interleaved: + Execution log file + (trimmomatic {log}, trimgalore {txt}, fastp {log}) + pattern: "*.{log,txt}" + - report: type: file description: | - Structure: [ val(meta), path(fastq.gz) ] - Write paired-end reads to a single file, interleaving mate 1 and mate 2 reads - pattern: "*.paired.fastq.gz" + Execution report + (trimmomatic {summary}, trimgalore {html,zip}, fastp {html}) + pattern: "*.{summary,html,zip}" - versions: type: file description: | @@ -151,7 +86,9 @@ output: pattern: "versions.yml" - multiqc_files: type: file - description: MultiQC-compatible output files from tools used in preprocessing + description: | + MultiQC-compatible output files from tools used in preprocessing + (trimmomatic, cutadapt, bbduk, leehom, fastp, adapterremoval) authors: - "@kornkv" - "@vagkaratzas" diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index 86637babc1ab..4d311b8870bb 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -48,18 +48,20 @@ nextflow_workflow { } then { - assert workflow.success - assert snapshot( - workflow.out.reads[0][1], - workflow.out.discarded_reads.collect { file(it[1]).name }, - workflow.out.trimmomatic_trim_log[0][1], - workflow.out.trimmomatic_summary[0][1], - path(workflow.out.trimgalore_log[0][1]).readLines().size(), - file(workflow.out.fastp_html[0][1]).name, - path(workflow.out.fastp_log[0][1]).readLines().size(), - workflow.out.multiqc_files.collect { file(it[1]).name }, - workflow.out.versions.collect { path(it).yaml } - ).match() + assertAll( + assert workflow.success + assert snapshot( + workflow.out.reads[0][1], + workflow.out.discarded_reads.collect { file(it[1]).name }, + workflow.out.trimmomatic_trim_log[0][1], + workflow.out.trimmomatic_summary[0][1], + path(workflow.out.trimgalore_log[0][1]).readLines().size(), + file(workflow.out.fastp_html[0][1]).name, + path(workflow.out.fastp_log[0][1]).readLines().size(), + workflow.out.multiqc_files.collect { file(it[1]).name }, + workflow.out.versions.collect { path(it).yaml } + ).match() + ) } } @@ -97,20 +99,22 @@ nextflow_workflow { } then { - assert workflow.success - assert snapshot( - workflow.out.reads[0][1], - workflow.out.merged_reads[0][1], - workflow.out.discarded_reads.collect { file(it[1]).name }, - workflow.out.trimmomatic_trim_log[0][1], - workflow.out.trimmomatic_summary[0][1], - path(workflow.out.trimgalore_log[0][1][0]).readLines().size(), - path(workflow.out.trimgalore_log[0][1][1]).readLines().size(), - file(workflow.out.fastp_html[0][1]).name, - path(workflow.out.fastp_log[0][1]).readLines().size(), - workflow.out.multiqc_files.collect { file(it[1]).name }, - workflow.out.versions.collect { path(it).yaml } - ).match() + assertAll( + assert workflow.success + assert snapshot( + workflow.out.reads[0][1], + workflow.out.merged_reads[0][1], + workflow.out.discarded_reads.collect { file(it[1]).name }, + workflow.out.trimmomatic_trim_log[0][1], + workflow.out.trimmomatic_summary[0][1], + path(workflow.out.trimgalore_log[0][1][0]).readLines().size(), + path(workflow.out.trimgalore_log[0][1][1]).readLines().size(), + file(workflow.out.fastp_html[0][1]).name, + path(workflow.out.fastp_log[0][1]).readLines().size(), + workflow.out.multiqc_files.collect { file(it[1]).name }, + workflow.out.versions.collect { path(it).yaml } + ).match() + ) } } @@ -148,19 +152,21 @@ nextflow_workflow { } then { - assert workflow.success - assert snapshot( - workflow.out.reads[0][1], - workflow.out.discarded_reads.collect { file(it[1]).name }, - workflow.out.trimmomatic_trim_log[0][1], - workflow.out.trimmomatic_summary[0][1], - path(workflow.out.trimgalore_log[0][1][0]).readLines().size(), - path(workflow.out.trimgalore_log[0][1][1]).readLines().size(), - file(workflow.out.fastp_html[0][1]).name, - path(workflow.out.fastp_log[0][1]).readLines().size(), - workflow.out.multiqc_files.collect { file(it[1]).name }, - workflow.out.versions.collect { path(it).yaml } - ).match() + assertAll( + assert workflow.success + assert snapshot( + workflow.out.reads[0][1], + workflow.out.discarded_reads.collect { file(it[1]).name }, + workflow.out.trimmomatic_trim_log[0][1], + workflow.out.trimmomatic_summary[0][1], + path(workflow.out.trimgalore_log[0][1][0]).readLines().size(), + path(workflow.out.trimgalore_log[0][1][1]).readLines().size(), + file(workflow.out.fastp_html[0][1]).name, + path(workflow.out.fastp_log[0][1]).readLines().size(), + workflow.out.multiqc_files.collect { file(it[1]).name }, + workflow.out.versions.collect { path(it).yaml } + ).match() + ) } } @@ -193,15 +199,17 @@ nextflow_workflow { } then { - assert workflow.success - assert snapshot( - workflow.out.reads[0][1], - workflow.out.discarded_reads.collect { file(it[1]).name }, - file(workflow.out.fastp_html[0][1]).name, - path(workflow.out.fastp_log[0][1]).readLines().size(), - workflow.out.multiqc_files.collect { file(it[1]).name }, - workflow.out.versions.collect { path(it).yaml } - ).match() + assertAll( + assert workflow.success + assert snapshot( + workflow.out.reads[0][1], + workflow.out.discarded_reads.collect { file(it[1]).name }, + file(workflow.out.fastp_html[0][1]).name, + path(workflow.out.fastp_log[0][1]).readLines().size(), + workflow.out.multiqc_files.collect { file(it[1]).name }, + workflow.out.versions.collect { path(it).yaml } + ).match() + ) } } @@ -238,8 +246,10 @@ nextflow_workflow { } then { - assert workflow.success - assert snapshot(workflow.out).match() + assertAll( + assert workflow.success + assert snapshot(workflow.out).match() + ) } } From d7519d60b97018f3aba22ce0708f9ca55ace99af Mon Sep 17 00:00:00 2001 From: vagkaratzas Date: Fri, 19 Dec 2025 11:50:41 +0000 Subject: [PATCH 83/83] nf-tests updated --- .../tests/main.nf.test | 298 +++++++----- .../tests/main.nf.test.snap | 458 +++++------------- 2 files changed, 280 insertions(+), 476 deletions(-) diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test index 4d311b8870bb..b18b22e1ee98 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test @@ -3,7 +3,6 @@ nextflow_workflow { name "Test Subworkflow FASTQ_REMOVEADAPTERS_MERGE" script "../main.nf" workflow "FASTQ_REMOVEADAPTERS_MERGE" - config './nextflow.config' tag "subworkflows" tag "subworkflows_nfcore" @@ -17,7 +16,7 @@ nextflow_workflow { tag "fastp" tag "adapterremoval" - test("sarscov2 - fastq - single-end") { + test("sarscov2 - fastq - trimmomatic - single-end") { config "./nextflow_SE.config" when { params { @@ -26,100 +25,103 @@ nextflow_workflow { } workflow { """ - input[0] = [ + input[0] = channel.of([ [ id:'test', single_end:true ], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) - ] - - input[1] = false // skip_trimmomatic - input[2] = false // skip_cutadapt - input[3] = false // skip_trimgalore - input[4] = false // skip_bbduk - input[5] = [] // contaminants - input[6] = false // skip_leehom - input[7] = false // skip_fastp - input[8] = false // fastp_discard_trimmed_pass - input[9] = true // fastp_save_trimmed_fail - input[10] = params.save_merged - input[11] = false // skip_adapterremoval - input[12] = [] // text adapters + ]) + input[1] = "trimmomatic" // val_adapter_tool + input[2] = [] // ch_adapters + input[3] = params.save_merged // val_save_merged + input[4] = false // val_fastp_discard_trimmed_pass + input[5] = false // val_fastp_save_trimmed_fail """ } } then { assertAll( - assert workflow.success - assert snapshot( - workflow.out.reads[0][1], - workflow.out.discarded_reads.collect { file(it[1]).name }, - workflow.out.trimmomatic_trim_log[0][1], - workflow.out.trimmomatic_summary[0][1], - path(workflow.out.trimgalore_log[0][1]).readLines().size(), - file(workflow.out.fastp_html[0][1]).name, - path(workflow.out.fastp_log[0][1]).readLines().size(), + { assert workflow.success }, + { assert snapshot( + workflow.out.processed_reads[0][1], + workflow.out.logfile[0][1], + workflow.out.report[0][1], workflow.out.multiqc_files.collect { file(it[1]).name }, workflow.out.versions.collect { path(it).yaml } - ).match() + ).match()} ) } } - test("sarscov2 - fastq - paired-end") { - config "./nextflow_PE.config" + test("sarscov2 - fastq - cutadapt - paired-end") { + config "./nextflow.config" when { params { - save_merged = true + save_merged = false adapterremoval_args = save_merged ? "--collapse" : "" } workflow { """ - input[0] = [ + input[0] = channel.of([ [ id:'test', single_end:false ], [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] - ] + ]) + input[1] = "cutadapt" // val_adapter_tool + input[2] = [] // ch_adapters + input[3] = params.save_merged // val_save_merged + input[4] = false // val_fastp_discard_trimmed_pass + input[5] = false // val_fastp_save_trimmed_fail + """ + } + } - input[1] = false // skip_trimmomatic - input[2] = false // skip_cutadapt - input[3] = false // skip_trimgalore - input[4] = false // skip_bbduk - input[5] = [] // contaminants - input[6] = false // skip_leehom - input[7] = false // skip_fastp - input[8] = false // fastp_discard_trimmed_pass - input[9] = true // fastp_save_trimmed_fail - input[10] = params.save_merged - input[11] = false // skip_adapterremoval - input[12] = [] // text adapters + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.processed_reads[0][1], + workflow.out.multiqc_files.collect { file(it[1]).name } + ).match()} + ) + } + } + + test("sarscov2 - fastq - trimgalore - single-end") { + when { + params { + save_merged = false + adapterremoval_args = save_merged ? "--collapse" : "" + } + workflow { + """ + input[0] = channel.of([ + [ id:'test', single_end:true ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ]) + input[1] = "trimgalore" // val_adapter_tool + input[2] = [] // ch_adapters + input[3] = params.save_merged // val_save_merged + input[4] = false // val_fastp_discard_trimmed_pass + input[5] = false // val_fastp_save_trimmed_fail """ } } then { assertAll( - assert workflow.success - assert snapshot( - workflow.out.reads[0][1], - workflow.out.merged_reads[0][1], - workflow.out.discarded_reads.collect { file(it[1]).name }, - workflow.out.trimmomatic_trim_log[0][1], - workflow.out.trimmomatic_summary[0][1], - path(workflow.out.trimgalore_log[0][1][0]).readLines().size(), - path(workflow.out.trimgalore_log[0][1][1]).readLines().size(), - file(workflow.out.fastp_html[0][1]).name, - path(workflow.out.fastp_log[0][1]).readLines().size(), - workflow.out.multiqc_files.collect { file(it[1]).name }, - workflow.out.versions.collect { path(it).yaml } - ).match() + { assert workflow.success }, + { assert snapshot( + workflow.out.processed_reads[0][1], + path(workflow.out.logfile[0][1]).readLines().size() + ).match()} ) } } - test("sarscov2 - fastq - paired-end - no-merge") { - config "./nextflow_PE.config" + test("sarscov2 - fastq - bbduk - paired-end") { + config "./nextflow.config" when { params { save_merged = false @@ -127,94 +129,143 @@ nextflow_workflow { } workflow { """ - input[0] = [ - [ id:'test', single_end:false ], + input[0] = channel.of([ + [ id:'test_bbduk', single_end:false ], [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] - ] + ]) + input[1] = "bbduk" // val_adapter_tool + input[2] = [] // ch_adapters + input[3] = params.save_merged // val_save_merged + input[4] = false // val_fastp_discard_trimmed_pass + input[5] = false // val_fastp_save_trimmed_fail + """ + } + } - input[1] = false // skip_trimmomatic - input[2] = false // skip_cutadapt - input[3] = false // skip_trimgalore - input[4] = false // skip_bbduk - input[5] = [] // contaminants - input[6] = false // skip_leehom - input[7] = false // skip_fastp - input[8] = false // fastp_discard_trimmed_pass - input[9] = true // fastp_save_trimmed_fail - input[10] = params.save_merged - input[11] = false // skip_adapterremoval - input[12] = [] // text adapters + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.processed_reads[0][1], + workflow.out.multiqc_files.collect { file(it[1]).name } + ).match()} + ) + } + } + + test("sarscov2 - fastq - leehom - single-end") { + when { + params { + save_merged = false + adapterremoval_args = save_merged ? "--collapse" : "" + } + workflow { + """ + input[0] = channel.of([ + [ id:'test', single_end:true ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ]) + input[1] = "leehom" // val_adapter_tool + input[2] = [] // ch_adapters + input[3] = params.save_merged // val_save_merged + input[4] = false // val_fastp_discard_trimmed_pass + input[5] = false // val_fastp_save_trimmed_fail """ } } then { assertAll( - assert workflow.success - assert snapshot( - workflow.out.reads[0][1], + { assert workflow.success }, + { assert snapshot( + workflow.out.processed_reads[0][1], workflow.out.discarded_reads.collect { file(it[1]).name }, - workflow.out.trimmomatic_trim_log[0][1], - workflow.out.trimmomatic_summary[0][1], - path(workflow.out.trimgalore_log[0][1][0]).readLines().size(), - path(workflow.out.trimgalore_log[0][1][1]).readLines().size(), - file(workflow.out.fastp_html[0][1]).name, - path(workflow.out.fastp_log[0][1]).readLines().size(), workflow.out.multiqc_files.collect { file(it[1]).name }, workflow.out.versions.collect { path(it).yaml } - ).match() + ).match()} ) } } - test("sarscov2 - fastq - single-end - with-skips") { + test("sarscov2 - fastq - fastp - single-end") { when { params { save_merged = false + adapterremoval_args = save_merged ? "--collapse" : "" } workflow { """ - input[0] = [ + input[0] = channel.of([ [ id:'test', single_end:true ], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) - ] - - input[1] = true // skip_trimmomatic - input[2] = false // skip_cutadapt - input[3] = true // skip_trimgalore - input[4] = false // skip_bbduk - input[5] = [] // contaminants - input[6] = true // skip_leehom - input[7] = false // skip_fastp - input[8] = false // fastp_discard_trimmed_pass - input[9] = true // fastp_save_trimmed_fail - input[10] = params.save_merged - input[11] = true // skip_adapterremoval - input[12] = [] // text adapters + ]) + input[1] = "fastp" // val_adapter_tool + input[2] = [] // ch_adapters + input[3] = params.save_merged // val_save_merged + input[4] = false // val_fastp_discard_trimmed_pass + input[5] = true // val_fastp_save_trimmed_fail """ } } then { assertAll( - assert workflow.success - assert snapshot( - workflow.out.reads[0][1], - workflow.out.discarded_reads.collect { file(it[1]).name }, - file(workflow.out.fastp_html[0][1]).name, - path(workflow.out.fastp_log[0][1]).readLines().size(), + { assert workflow.success }, + { assert snapshot( + workflow.out.processed_reads[0][1], + workflow.out.discarded_reads[0][1], + path(workflow.out.logfile[0][1]).readLines().size(), + path(workflow.out.report[0][1]).readLines().size(), workflow.out.multiqc_files.collect { file(it[1]).name }, workflow.out.versions.collect { path(it).yaml } - ).match() + ).match()} ) } } - test("sarscov2 - fastq - single-end - stub") { + test("sarscov2 - fastq - adapterremoval - paired-end - merge") { + config "./nextflow_PE.config" + when { + params { + save_merged = true + adapterremoval_args = save_merged ? "--collapse" : "" + } + workflow { + """ + input[0] = channel.of([ + [ id:'test', single_end:false ], + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = "adapterremoval" // val_adapter_tool + input[2] = [] // ch_adapters + input[3] = params.save_merged // val_save_merged + input[4] = false // val_fastp_discard_trimmed_pass + input[5] = false // val_fastp_save_trimmed_fail + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.processed_reads[0][1], + workflow.out.discarded_reads.collect { file(it[1]).name }, + workflow.out.versions.collect { path(it).yaml }, + workflow.out.multiqc_files.collect { file(it[1]).name } + ).match()} + ) + } + } + test("sarscov2 - fastq - trimmomatic - paired-end - stub") { + config "./nextflow_PE.config" options "-stub" when { @@ -225,30 +276,25 @@ nextflow_workflow { workflow { """ input[0] = [ - [ id:'test', single_end:true ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + [ id:'test', single_end:false ], + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ] ] - - input[1] = false // skip_trimmomatic - input[2] = false // skip_cutadapt - input[3] = false // skip_trimgalore - input[4] = false // skip_bbduk - input[5] = [] // contaminants - input[6] = false // skip_leehom - input[7] = false // skip_fastp - input[8] = false // fastp_discard_trimmed_pass - input[9] = true // fastp_save_trimmed_fail - input[10] = params.save_merged - input[11] = false // skip_adapterremoval - input[12] = [] // text adapters + input[1] = "trimmomatic" // val_adapter_tool + input[2] = [] // ch_adapters + input[3] = params.save_merged // val_save_merged + input[4] = false // val_fastp_discard_trimmed_pass + input[5] = false // val_fastp_save_trimmed_fail """ } } then { assertAll( - assert workflow.success - assert snapshot(workflow.out).match() + { assert workflow.success }, + { assert snapshot(workflow.out).match() } ) } } diff --git a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap index 54ac2a7384aa..ff92826858df 100644 --- a/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_removeadapters_merge/tests/main.nf.test.snap @@ -1,26 +1,39 @@ { - "sarscov2 - fastq - single-end - with-skips": { + "sarscov2 - fastq - trimmomatic - single-end": { "content": [ - "test.fastp.fastq.gz:md5,e051aedfa286d0567c83870d93ed93a3", - [ - "test.fail.fastq.gz" - ], - "test.fastp.html", - 32, + "test.SE.paired.trim.fastq.gz:md5,e68abbd3b88f7ec12940a4f5c2b8bfb9", + "test_trim.log:md5,e4c3f619e9b0e26847f8f3e3d9af319b", + "test.summary:md5,24c973237557a1439c775ca19a5deaa5", [ - "test.bbduk.log", - "test.cutadapt.log", - "test.fastp.json" + "test_out.log" ], [ { - "FASTQ_REMOVEADAPTERS_MERGE:FASTP": { - "fastp": "1.0.1" + "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { + "trimmomatic": 0.39 } - }, + } + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-19T11:19:19.104684739" + }, + "sarscov2 - fastq - leehom - single-end": { + "content": [ + "test.fq.gz:md5,304af6f5f6bb58c70abf7924eacfa175", + [ + "test.fail.fq.gz" + ], + [ + "test.log" + ], + [ { - "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { - "bbmap": 39.18 + "FASTQ_REMOVEADAPTERS_MERGE:LEEHOM": { + "leehom": "1.2.15" } } ] @@ -29,105 +42,47 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-12T14:49:19.909628033" + "timestamp": "2025-12-19T11:48:35.122105584" }, - "sarscov2 - fastq - single-end - stub": { + "sarscov2 - fastq - trimmomatic - paired-end - stub": { "content": [ { "0": [ [ { "id": "test", - "single_end": true + "single_end": false }, - "test.truncated.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + [ + "test.paired.trim_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.paired.trim_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] ] ], "1": [ - - ], - "10": [ - - ], - "11": [ - "versions.yml:md5,2d5c9b99267e97292e2a581635bd72f7", - "versions.yml:md5,aa418419664a944b74696ee0e9ef1c7a", - "versions.yml:md5,ba074f9db361b3f8d0a8cc93c3907a91", - "versions.yml:md5,bcfe22d952cc3ae0ac5ff685e16fa4a5", - "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" - ], - "12": [ - [ - { - "id": "test", - "single_end": true - }, - "test.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.cutadapt.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ], [ { "id": "test", - "single_end": true + "single_end": false }, - "test.settings:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.unpaired.trim_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ], [ { "id": "test", - "single_end": true + "single_end": false }, - "test_out.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.unpaired.trim_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "2": [ - [ - { - "id": "test", - "single_end": true - }, - "test.discarded.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.fail.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] + ], "3": [ [ { "id": "test", - "single_end": true + "single_end": false }, "test_trim.log:md5,d41d8cd98f00b204e9800998ecf8427e" ] @@ -136,183 +91,83 @@ [ { "id": "test", - "single_end": true + "single_end": false }, "test.summary:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "5": [ - [ - { - "id": "test", - "single_end": true - }, - "test.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "versions.yml:md5,134eb815a4e39fddbfa930d8023aafaa" ], "6": [ - - ], - "7": [ - - ], - "8": [ - [ - { - "id": "test", - "single_end": true - }, - "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "9": [ [ { "id": "test", - "single_end": true + "single_end": false }, - "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test_out.log:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "adapterremoval_paired_interleaved": [ - ], "discarded_reads": [ [ { "id": "test", - "single_end": true - }, - "test.discarded.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ], - [ - { - "id": "test", - "single_end": true + "single_end": false }, - "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test.unpaired.trim_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ], [ { "id": "test", - "single_end": true - }, - "test.fail.fq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "fastp_html": [ - [ - { - "id": "test", - "single_end": true + "single_end": false }, - "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.unpaired.trim_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "fastp_log": [ + "logfile": [ [ { "id": "test", - "single_end": true + "single_end": false }, - "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + "test_trim.log:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "merged_reads": [ - ], "multiqc_files": [ [ { "id": "test", - "single_end": true - }, - "test.bbduk.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.cutadapt.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - [ - { - "id": "test", - "single_end": true - }, - "test.settings:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - [ - { - "id": "test", - "single_end": true + "single_end": false }, "test_out.log:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "reads": [ - [ - { - "id": "test", - "single_end": true - }, - "test.truncated.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] - ], - "trimgalore_html": [ + "paired_interleaved": [ ], - "trimgalore_log": [ + "processed_reads": [ [ { "id": "test", - "single_end": true + "single_end": false }, - "test.fastq.gz_trimming_report.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "test.paired.trim_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.paired.trim_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] ] ], - "trimgalore_zip": [ - - ], - "trimmomatic_summary": [ + "report": [ [ { "id": "test", - "single_end": true + "single_end": false }, "test.summary:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "trimmomatic_trim_log": [ - [ - { - "id": "test", - "single_end": true - }, - "test_trim.log:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], "versions": [ - "versions.yml:md5,2d5c9b99267e97292e2a581635bd72f7", - "versions.yml:md5,aa418419664a944b74696ee0e9ef1c7a", - "versions.yml:md5,ba074f9db361b3f8d0a8cc93c3907a91", - "versions.yml:md5,bcfe22d952cc3ae0ac5ff685e16fa4a5", - "versions.yml:md5,ea028122f5baa3d73d93e46d4eb742fd" + "versions.yml:md5,134eb815a4e39fddbfa930d8023aafaa" ] } ], @@ -320,185 +175,88 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-15T16:11:48.259971231" + "timestamp": "2025-12-19T11:19:48.58678264" }, - "sarscov2 - fastq - paired-end": { + "sarscov2 - fastq - cutadapt - paired-end": { "content": [ [ - "test.pair1.truncated.fastq.gz:md5,b865b4a1d2a7ac9c1caee464e9857da0", - "test.pair2.truncated.fastq.gz:md5,1ec9f8b98d3c6dbf956db0782228b29c" + "test_1.trim.fastq.gz:md5,682dab8e982563cffac2bd60bf7444f4", + "test_2.trim.fastq.gz:md5,1a1e8ab23af40e6474be0cdf82fab907" ], - "test.collapsed.fastq.gz:md5,984b6edf9c613449d2f7ce6dbe0f5550", [ - "test.discarded.fastq.gz", - "test.fail.fq.gz", - "test.paired.fail.fastq.gz", - "test.unpaired.trim_1.fastq.gz", - "test.unpaired.trim_2.fastq.gz", - "test_1.fail.fastq.gz", - "test_2.fail.fastq.gz", - "test_r1.fail.fq.gz", - "test_r2.fail.fq.gz" - ], - "test_trim.log:md5,9629761761a34576b3484bf4174f681f", - "test.summary:md5,9698e5e5c060bbe64588998fe35f8d71", - 59, - 62, - "test.fastp.html", - 51, + "test.cutadapt.log" + ] + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-19T11:19:27.959952445" + }, + "sarscov2 - fastq - bbduk - paired-end": { + "content": [ [ - "test.bbduk.log", - "test.cutadapt.log", - "test.fastp.json", - "test.log", - "test.settings", - "test_out.log" + "test_bbduk_1.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec", + "test_bbduk_2.fastq.gz:md5,2ebae722295ea66d84075a3b042e2b42" ], [ - { - "FASTQ_REMOVEADAPTERS_MERGE:ADAPTERREMOVAL_PE": { - "adapterremoval": "2.3.2" - } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:FASTP": { - "fastp": "1.0.1" - } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:LEEHOM": { - "leehom": "1.2.15" - } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { - "bbmap": 39.18 - } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { - "trimmomatic": 0.39 - } - } + "test_bbduk.bbduk.log" ] ], "meta": { "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-15T16:11:16.074223859" + "timestamp": "2025-12-19T11:19:41.651709543" }, - "sarscov2 - fastq - single-end": { + "sarscov2 - fastq - trimgalore - single-end": { "content": [ - "test.truncated.fastq.gz:md5,6dcea64429b2bcf5e31751f9c8041914", - [ - "test.discarded.fastq.gz", - "test.fail.fastq.gz", - "test.fail.fq.gz" - ], - "test_trim.log:md5,e4c3f619e9b0e26847f8f3e3d9af319b", - "test.summary:md5,24c973237557a1439c775ca19a5deaa5", - 60, - "test.fastp.html", - 32, + "test_trimmed.fq.gz:md5,566d44cca0d22c522d6cf0e50c7165dc", + 60 + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2025-12-19T11:19:34.98214978" + }, + "sarscov2 - fastq - adapterremoval - paired-end - merge": { + "content": [ + "test.collapsed.fastq.gz:md5,369452751050a7f1e31b839702d61417", [ - "test.bbduk.log", - "test.cutadapt.log", - "test.fastp.json", - "test.log", - "test.settings", - "test_out.log" + "test.discarded.fastq.gz" ], [ { - "FASTQ_REMOVEADAPTERS_MERGE:FASTP": { - "fastp": "1.0.1" - } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:ADAPTERREMOVAL_SE": { + "FASTQ_REMOVEADAPTERS_MERGE:ADAPTERREMOVAL_PE": { "adapterremoval": "2.3.2" } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:LEEHOM": { - "leehom": "1.2.15" - } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { - "bbmap": 39.18 - } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { - "trimmomatic": 0.39 - } } + ], + [ + "test.settings" ] ], "meta": { "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-15T16:11:01.68533947" + "timestamp": "2025-12-19T11:48:05.024036426" }, - "sarscov2 - fastq - paired-end - no-merge": { + "sarscov2 - fastq - fastp - single-end": { "content": [ + "test.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7", + "test.fail.fastq.gz:md5,3e4aaadb66a5b8fc9b881bf39c227abd", + 32, + 2394, [ - "test.pair1.truncated.fastq.gz:md5,b042d3460f77b69f0a4d2a5cb20b1b25", - "test.pair2.truncated.fastq.gz:md5,510c140a51b7b0457e92e658113acbdc" - ], - [ - "test.discarded.fastq.gz", - "test.fail.fq.gz", - "test.paired.fail.fastq.gz", - "test.unpaired.trim_1.fastq.gz", - "test.unpaired.trim_2.fastq.gz", - "test_1.fail.fastq.gz", - "test_2.fail.fastq.gz", - "test_r1.fail.fq.gz", - "test_r2.fail.fq.gz" - ], - "test_trim.log:md5,9629761761a34576b3484bf4174f681f", - "test.summary:md5,9698e5e5c060bbe64588998fe35f8d71", - 59, - 62, - "test.fastp.html", - 51, - [ - "test.bbduk.log", - "test.cutadapt.log", - "test.fastp.json", - "test.log", - "test.settings", - "test_out.log" + "test.fastp.json" ], [ - { - "FASTQ_REMOVEADAPTERS_MERGE:ADAPTERREMOVAL_PE": { - "adapterremoval": "2.3.2" - } - }, { "FASTQ_REMOVEADAPTERS_MERGE:FASTP": { "fastp": "1.0.1" } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:LEEHOM": { - "leehom": "1.2.15" - } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:BBMAP_BBDUK": { - "bbmap": 39.18 - } - }, - { - "FASTQ_REMOVEADAPTERS_MERGE:TRIMMOMATIC": { - "trimmomatic": 0.39 - } } ] ], @@ -506,6 +264,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2025-12-15T16:11:29.80825695" + "timestamp": "2025-12-19T11:49:02.995746975" } } \ No newline at end of file