diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a8c20d9..986c91f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,6 +70,11 @@ the last release have been listed below for reference. | python | 3.8.3 | 3.12.12 | | multiqc | 1.25.1 | 1.33 | | deeptools | 3.5.5 | 3.5.6 | +| bowtie2 | 2.5.2 | 2.5.4 | +| picard | 3.2.0 | 3.4.0 | +| samtools | 1.15.1 | 1.20 | +| bwa | 0.7.18 | 0.7.19 | +| chromap | 0.2.6 | 0.3.2 | | | | | ## [[2.1.0](https://github.com/nf-core/chipseq/releases/tag/2.1.0)] - 2024-10-07 diff --git a/conf/modules.config b/conf/modules.config index 9022081e..087aeec1 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -26,8 +26,7 @@ process { ext.args = 'samplesheet.valid.csv' publishDir = [ path: { "${params.outdir}/pipeline_info" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + mode: params.publish_dir_mode ] } @@ -60,7 +59,6 @@ process { publishDir = [ path: { "${params.outdir}/genome/index" }, mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] } @@ -78,7 +76,6 @@ process { publishDir = [ path: { "${params.outdir}/genome" }, mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] } @@ -227,19 +224,32 @@ process { withName: 'CHROMAP_INDEX' { publishDir = [ path: { "${params.outdir}/genome/index/${params.aligner}" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + mode: params.publish_dir_mode ] } - withName: CHROMAP_CHROMAP { + withName: 'CHROMAP_CHROMAP' { ext.args = '-l 2000 --low-mem --SAM' ext.args3 = { meta.read_group ? "-r ${meta.read_group}" : '' } ext.prefix = { "${meta.id}.Lb" } publishDir = [ path: { "${params.outdir}/${params.aligner}/library" }, mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, + enabled: false + ] + } + + withName: '.*:FASTQ_ALIGN_CHROMAP:PICARD_ADDORREPLACEREADGROUPS' { + ext.args = { + [ + meta.read_group ? "--RGID ${meta.id} --RGSM ${meta.id - ~/_T\d+$/} --RGPL ILLUMINA --RGLB ${meta.id} --RGPU 1" : '', + params.seq_center ? "--RGCN ${params.seq_center}" : '' + ].join(' ').trim() + } + ext.prefix = { "${meta.id}.Lb.updated_readgroups" } + publishDir = [ + path: { "${params.outdir}/${params.aligner}/library" }, + mode: params.publish_dir_mode, enabled: false ] } @@ -424,8 +434,7 @@ process { withName: 'MULTIQC_CUSTOM_PHANTOMPEAKQUALTOOLS' { publishDir = [ path: { "${params.outdir}/${params.aligner}/merged_library/phantompeakqualtools" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + mode: params.publish_dir_mode ] } @@ -575,7 +584,6 @@ process { publishDir = [ path: { "${params.outdir}/${params.aligner}/merged_library/macs3/${params.narrow_peak ? 'narrow_peak' : 'broad_peak'}/qc" }, mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -646,8 +654,7 @@ process { ext.prefix = { "${meta.id}.consensus_peaks" } publishDir = [ path: { "${params.outdir}/${params.aligner}/merged_library/macs3/${params.narrow_peak ? 'narrow_peak' : 'broad_peak'}/consensus/${meta.id}" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + mode: params.publish_dir_mode ] } @@ -666,8 +673,7 @@ process { ext.prefix = { "${meta.id}.consensus_peaks" } publishDir = [ path: { "${params.outdir}/${params.aligner}/merged_library/macs3/${params.narrow_peak ? 'narrow_peak' : 'broad_peak'}/consensus/${meta.id}/deseq2" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + mode: params.publish_dir_mode ] } @@ -698,8 +704,7 @@ process { ext.args = params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' publishDir = [ path: { "${params.outdir}/multiqc/${params.narrow_peak ? 'narrow_peak' : 'broad_peak'}" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + mode: params.publish_dir_mode ] } } diff --git a/modules.json b/modules.json index 621953f3..3693b49d 100644 --- a/modules.json +++ b/modules.json @@ -12,7 +12,7 @@ }, "bowtie2/align": { "branch": "master", - "git_sha": "92b8df948fd8cdb223e051f5f5e414818a073ee0", + "git_sha": "0cd85f32cf1a1828205b16e4267277ba9457570b", "installed_by": ["fastq_align_bowtie2", "modules"] }, "bowtie2/build": { @@ -27,12 +27,12 @@ }, "bwa/mem": { "branch": "master", - "git_sha": "707241c72951f24fd89982c4c80c5983a4c437ef", + "git_sha": "2fb127c8fd13de0adaa676df7169131e45c0b114", "installed_by": ["fastq_align_bwa", "modules"] }, "chromap/chromap": { "branch": "master", - "git_sha": "e753770db613ce014b3c4bc94f6cba443427b726", + "git_sha": "f2f969a4ee32243c7fab75f341f9be1dd3ce1a23", "installed_by": ["fastq_align_chromap", "modules"], "patch": "modules/nf-core/chromap/chromap/chromap-chromap.diff" }, @@ -101,6 +101,29 @@ "git_sha": "e753770db613ce014b3c4bc94f6cba443427b726", "installed_by": ["modules"] }, + "picard/addorreplacereadgroups": { + "branch": "master", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", + "installed_by": [ + "_", + "a", + "c", + "f", + "g", + "h", + "i", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "fastq_align_chromap" + ] + }, "picard/collectmultiplemetrics": { "branch": "master", "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", @@ -108,7 +131,7 @@ }, "picard/markduplicates": { "branch": "master", - "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", "installed_by": ["bam_markduplicates_picard", "modules"] }, "picard/mergesamfiles": { @@ -128,28 +151,27 @@ }, "samtools/flagstat": { "branch": "master", - "git_sha": "1d2fbdcbca677bbe8da0f9d0d2bb7c02f2cab1c9", - "installed_by": ["bam_stats_samtools", "modules"], - "patch": "modules/nf-core/samtools/flagstat/samtools-flagstat.diff" + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", + "installed_by": ["bam_stats_samtools", "modules"] }, "samtools/idxstats": { "branch": "master", - "git_sha": "1d2fbdcbca677bbe8da0f9d0d2bb7c02f2cab1c9", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", "installed_by": ["bam_stats_samtools", "modules"] }, "samtools/index": { "branch": "master", - "git_sha": "1d2fbdcbca677bbe8da0f9d0d2bb7c02f2cab1c9", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", "installed_by": ["bam_markduplicates_picard", "bam_sort_stats_samtools", "modules"] }, "samtools/sort": { "branch": "master", - "git_sha": "5cb9a8694da0a0e550921636bb60bc8c56445fd7", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", "installed_by": ["bam_sort_stats_samtools", "modules"] }, "samtools/stats": { "branch": "master", - "git_sha": "fe93fde0845f907fc91ad7cc7d797930408824df", + "git_sha": "6d46786420b4d7bc88eba026eb389c0c5535d120", "installed_by": ["bam_stats_samtools", "modules"] }, "subread/featurecounts": { @@ -188,32 +210,32 @@ "nf-core": { "bam_markduplicates_picard": { "branch": "master", - "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", + "git_sha": "1298fbd2004c2913d6682ce4a419647d97a8fc3f", "installed_by": ["subworkflows"] }, "bam_sort_stats_samtools": { "branch": "master", - "git_sha": "7ac6cbe7c17c2dad685da7f70496c8f48ea48687", + "git_sha": "156feda0cb6589cd29c04902004fa3b53bc00205", "installed_by": ["fastq_align_bowtie2", "fastq_align_bwa", "fastq_align_chromap"] }, "bam_stats_samtools": { "branch": "master", - "git_sha": "7ac6cbe7c17c2dad685da7f70496c8f48ea48687", + "git_sha": "156feda0cb6589cd29c04902004fa3b53bc00205", "installed_by": ["bam_markduplicates_picard", "bam_sort_stats_samtools"] }, "fastq_align_bowtie2": { "branch": "master", - "git_sha": "9afa0584136287aa20fc18296f45f103c0c4e69a", + "git_sha": "a0961c41021561ac7cf139f86bd7812a2f99e994", "installed_by": ["subworkflows"] }, "fastq_align_bwa": { "branch": "master", - "git_sha": "9afa0584136287aa20fc18296f45f103c0c4e69a", + "git_sha": "cbb7a6362981f07d2c26e43f8186025320569ffd", "installed_by": ["subworkflows"] }, "fastq_align_chromap": { "branch": "master", - "git_sha": "9afa0584136287aa20fc18296f45f103c0c4e69a", + "git_sha": "d92e0f8276a79d316fd324eae0edefeaf680804c", "installed_by": ["subworkflows"] }, "fastq_fastqc_umitools_trimgalore": { diff --git a/modules/nf-core/bowtie2/align/main.nf b/modules/nf-core/bowtie2/align/main.nf index 0a8c1a0c..9be0dfee 100644 --- a/modules/nf-core/bowtie2/align/main.nf +++ b/modules/nf-core/bowtie2/align/main.nf @@ -3,7 +3,7 @@ process BOWTIE2_ALIGN { label 'process_high' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/b4/b41b403e81883126c3227fc45840015538e8e2212f13abc9ae84e4b98891d51c/data' : 'community.wave.seqera.io/library/bowtie2_htslib_samtools_pigz:edeb13799090a2a6' }" @@ -22,7 +22,7 @@ process BOWTIE2_ALIGN { tuple val(meta), path("*.crai") , emit: crai , optional:true tuple val(meta), path("*.log") , emit: log tuple val(meta), path("*fastq.gz") , emit: fastq , optional:true - tuple val("${task.process}"), val('bowtie2'), eval("bowtie2 --version 2>&1 | sed -n '1s/.*bowtie2-align-s version //p'"), emit: versions_bowtie2, topic: versions + tuple val("${task.process}"), val('bowtie2'), eval("bowtie2 --version 2>&1 | sed -n 's/.*bowtie2-align-s version //p'"), emit: versions_bowtie2, topic: versions tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), emit: versions_samtools, topic: versions tuple val("${task.process}"), val('pigz'), eval("pigz --version 2>&1 | sed 's/pigz //'"), emit: versions_pigz, topic: versions @@ -83,9 +83,9 @@ process BOWTIE2_ALIGN { def extension = (args2 ==~ extension_pattern) ? (args2 =~ extension_pattern)[0][2].toLowerCase() : "bam" def create_unmapped = "" if (meta.single_end) { - create_unmapped = save_unaligned ? "touch ${prefix}.unmapped.fastq.gz" : "" + create_unmapped = save_unaligned ? "echo | gzip > ${prefix}.unmapped.fastq.gz" : "" } else { - create_unmapped = save_unaligned ? "touch ${prefix}.unmapped_1.fastq.gz && touch ${prefix}.unmapped_2.fastq.gz" : "" + create_unmapped = save_unaligned ? "echo | gzip > ${prefix}.unmapped_1.fastq.gz && echo | gzip > ${prefix}.unmapped_2.fastq.gz" : "" } if (!fasta && extension=="cram") error "Fasta reference is required for CRAM output" diff --git a/modules/nf-core/bowtie2/align/meta.yml b/modules/nf-core/bowtie2/align/meta.yml index 2d8051da..83e1487c 100644 --- a/modules/nf-core/bowtie2/align/meta.yml +++ b/modules/nf-core/bowtie2/align/meta.yml @@ -46,9 +46,10 @@ input: e.g. [ id:'test', single_end:false ] - fasta: type: file - description: Bowtie2 genome fasta file - pattern: "*.fasta" - ontologies: [] + description: Reference genome FASTA file + pattern: "*.{fa,fasta,fna}" + ontologies: + - edam: "http://edamontology.org/format_1929" - save_unaligned: type: boolean description: | @@ -130,7 +131,7 @@ output: - bowtie2: type: string description: The name of the tool - - "bowtie2 --version 2>&1 | sed -n '1s/.*bowtie2-align-s version //p'": + - "bowtie2 --version 2>&1 | sed -n 's/.*bowtie2-align-s version //p'": type: eval description: The expression to obtain the version of bowtie2 versions_samtools: @@ -162,7 +163,7 @@ topics: - bowtie2: type: string description: The name of the tool - - "bowtie2 --version 2>&1 | sed -n '1s/.*bowtie2-align-s version //p'": + - "bowtie2 --version 2>&1 | sed -n 's/.*bowtie2-align-s version //p'": type: eval description: The expression to obtain the version of bowtie2 - - ${task.process}: diff --git a/modules/nf-core/bowtie2/align/tests/bam.config b/modules/nf-core/bowtie2/align/tests/bam.config new file mode 100644 index 00000000..78caeaff --- /dev/null +++ b/modules/nf-core/bowtie2/align/tests/bam.config @@ -0,0 +1,8 @@ +process { + withName: BOWTIE2_BUILD { + ext.args = '--seed 1' + } + withName: BOWTIE2_ALIGN { + ext.args = '--seed 1' + } +} diff --git a/modules/nf-core/bowtie2/align/tests/large_index.config b/modules/nf-core/bowtie2/align/tests/large_index.config index b2f0c405..c9cb76ed 100644 --- a/modules/nf-core/bowtie2/align/tests/large_index.config +++ b/modules/nf-core/bowtie2/align/tests/large_index.config @@ -1,5 +1,8 @@ process { withName: BOWTIE2_BUILD { - ext.args = '--large-index' + ext.args = '--large-index --seed 1' + } + withName: BOWTIE2_ALIGN { + ext.args = '--seed 1' } } diff --git a/modules/nf-core/bowtie2/align/tests/main.nf.test b/modules/nf-core/bowtie2/align/tests/main.nf.test index 1705b66d..ab054781 100644 --- a/modules/nf-core/bowtie2/align/tests/main.nf.test +++ b/modules/nf-core/bowtie2/align/tests/main.nf.test @@ -9,8 +9,9 @@ nextflow_process { tag "bowtie2/build" tag "bowtie2/align" - test("sarscov2 - fastq, index, fasta, false, false - bam") { + test("sarscov2 - fastq, index, fasta_fai, false, true - bam") { + config "./bam.config" setup { run("BOWTIE2_BUILD") { script "../../build/main.nf" @@ -33,9 +34,12 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] input[1] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[2] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] input[3] = false //save_unaligned - input[4] = false //sort + input[4] = true //sort """ } } @@ -44,7 +48,11 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( + // Conda and docker version of bowtie2 produce different + // hashes. Therefore, testing whether file exists and bam + // statistics. file(process.out.bam[0][1]).name, + bam(process.out.bam[0][1], stringency: "silent").getStatistics(exclude:["sorted"]), process.out.log, process.out.fastq, process.out.findAll { key, val -> key.startsWith('versions') } @@ -54,7 +62,7 @@ nextflow_process { } - test("sarscov2 - fastq, index, fasta, false, false - sam") { + test("sarscov2 - fastq, index, fasta_fai, false, true - sam") { config "./sam.config" setup { @@ -63,7 +71,7 @@ nextflow_process { process { """ input[0] = [ - [ id:'test'], + [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] """ @@ -79,9 +87,12 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] input[1] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[2] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] input[3] = false //save_unaligned - input[4] = false //sort + input[4] = true //sort """ } } @@ -90,7 +101,8 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( - file(process.out.sam[0][1]).readLines()[0..4], + file(process.out.sam[0][1]).name, + bam(process.out.sam[0][1], stringency: "silent").getStatistics(exclude:["sorted"]), process.out.log, process.out.fastq, process.out.findAll { key, val -> key.startsWith('versions') } @@ -100,7 +112,7 @@ nextflow_process { } - test("sarscov2 - fastq, index, fasta, false, false - sam2") { + test("sarscov2 - fastq, index, fasta_fai, false, true - sam2") { config "./sam2.config" setup { @@ -109,7 +121,7 @@ nextflow_process { process { """ input[0] = [ - [ id:'test'], + [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] """ @@ -125,9 +137,12 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] input[1] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[2] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] input[3] = false //save_unaligned - input[4] = false //sort + input[4] = true //sort """ } } @@ -136,7 +151,8 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( - file(process.out.sam[0][1]).readLines()[0..4], + file(process.out.sam[0][1]).name, + bam(process.out.sam[0][1], stringency: "silent").getStatistics(exclude:["sorted"]), process.out.log, process.out.fastq, process.out.findAll { key, val -> key.startsWith('versions') } @@ -146,15 +162,16 @@ nextflow_process { } - test("sarscov2 - fastq, index, fasta, false, true - bam") { + test("sarscov2 - fastq, index, fasta_fai, true, true - bam") { + config "./bam.config" setup { run("BOWTIE2_BUILD") { script "../../build/main.nf" process { """ input[0] = [ - [ id:'test'], + [ id:'test' ], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] """ @@ -170,9 +187,12 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] input[1] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] - input[3] = false //save_unaligned - input[4] = false //sort + input[2] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[3] = true //save_unaligned + input[4] = true //sort """ } } @@ -181,7 +201,11 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( + // Conda and docker version of bowtie2 produce different + // hashes. Therefore, testing whether file exists and bam + // statistics. file(process.out.bam[0][1]).name, + bam(process.out.bam[0][1], stringency: "silent").getStatistics(exclude:["sorted"]), process.out.log, process.out.fastq, process.out.findAll { key, val -> key.startsWith('versions') } @@ -191,8 +215,9 @@ nextflow_process { } - test("sarscov2 - [fastq1, fastq2], index, fasta, false, false - bam") { + test("sarscov2 - [fastq1, fastq2], index, fasta_fai, false, true - bam") { + config "./bam.config" setup { run("BOWTIE2_BUILD") { script "../../build/main.nf" @@ -218,9 +243,12 @@ nextflow_process { ] ] input[1] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[2] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] input[3] = false //save_unaligned - input[4] = false //sort + input[4] = true //sort """ } } @@ -229,7 +257,11 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( + // Conda and docker version of bowtie2 produce different + // hashes. Therefore, testing whether file exists and bam + // statistics. file(process.out.bam[0][1]).name, + bam(process.out.bam[0][1], stringency: "silent").getStatistics(exclude:["sorted"]), process.out.log, process.out.fastq, process.out.findAll { key, val -> key.startsWith('versions') } @@ -239,8 +271,9 @@ nextflow_process { } - test("sarscov2 - [fastq1, fastq2], index, fasta, false, true - bam") { + test("sarscov2 - [fastq1, fastq2], index, fasta_fai, true, true - bam") { + config "./bam.config" setup { run("BOWTIE2_BUILD") { script "../../build/main.nf" @@ -266,9 +299,12 @@ nextflow_process { ] ] input[1] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] - input[3] = false //save_unaligned - input[4] = false //sort + input[2] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[3] = true //save_unaligned + input[4] = true //sort """ } } @@ -277,7 +313,11 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( + // Conda and docker version of bowtie2 produce different + // hashes. Therefore, testing whether file exists and bam + // statistics. file(process.out.bam[0][1]).name, + bam(process.out.bam[0][1], stringency: "silent").getStatistics(exclude:["sorted"]), process.out.log, process.out.fastq, process.out.findAll { key, val -> key.startsWith('versions') } @@ -287,7 +327,7 @@ nextflow_process { } - test("sarscov2 - fastq, large_index, fasta, false, false - bam") { + test("sarscov2 - fastq, large_index, fasta_fai, false, true - bam") { config "./large_index.config" setup { @@ -312,58 +352,12 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] input[1] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] - input[3] = false //save_unaligned - input[4] = false //sort - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert snapshot( - file(process.out.bam[0][1]).name, - process.out.log, - process.out.fastq, - process.out.findAll { key, val -> key.startsWith('versions') } - ).match() } - ) - } - - } - - test("sarscov2 - [fastq1, fastq2], large_index, fasta, false, false - bam") { - - config "./large_index.config" - setup { - run("BOWTIE2_BUILD") { - script "../../build/main.nf" - process { - """ - input[0] = [ - [ id:'test'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] - """ - } - } - } - - when { - 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[2] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] - input[1] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] input[3] = false //save_unaligned - input[4] = false //sort + input[4] = true //sort """ } } @@ -372,7 +366,11 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( + // Conda and docker version of bowtie2 produce different + // hashes. Therefore, testing whether file exists and bam + // statistics. file(process.out.bam[0][1]).name, + bam(process.out.bam[0][1], stringency: "silent").getStatistics(exclude:["sorted"]), process.out.log, process.out.fastq, process.out.findAll { key, val -> key.startsWith('versions') } @@ -382,8 +380,9 @@ nextflow_process { } - test("sarscov2 - [fastq1, fastq2], index, fasta, true, false - bam") { + test("sarscov2 - [fastq1, fastq2], large_index, fasta_fai, false, true - bam") { + config "./large_index.config" setup { run("BOWTIE2_BUILD") { script "../../build/main.nf" @@ -409,54 +408,12 @@ nextflow_process { ] ] input[1] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] - input[3] = false //save_unaligned - input[4] = false //sort - """ - } - } - - then { - assertAll ( - { assert process.success }, - { assert snapshot( - file(process.out.bam[0][1]).name, - process.out.log, - process.out.fastq, - process.out.findAll { key, val -> key.startsWith('versions') } - ).match() } - ) - } - - } - - test("sarscov2 - fastq, index, fasta, true, false - bam") { - - setup { - run("BOWTIE2_BUILD") { - script "../../build/main.nf" - process { - """ - input[0] = [ - [ id:'test'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] - """ - } - } - } - - 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[2] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] - input[1] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] input[3] = false //save_unaligned - input[4] = false //sort + input[4] = true //sort """ } } @@ -465,18 +422,21 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( + // Conda and docker version of bowtie2 produce different + // hashes. Therefore, testing whether file exists and bam + // statistics. file(process.out.bam[0][1]).name, + bam(process.out.bam[0][1], stringency: "silent").getStatistics(exclude:["sorted"]), process.out.log, process.out.fastq, process.out.findAll { key, val -> key.startsWith('versions') } ).match() } - ) } } - test("sarscov2 - [fastq1, fastq2], index, fasta, true, true - cram") { + test("sarscov2 - [fastq1, fastq2], index, fasta_fai, false, true - cram") { config "./cram_crai.config" setup { @@ -497,14 +457,20 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map + [ + id:'test', + single_end:false, + fasta:'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/sarscov2/genome/genome.fasta' ], // meta map + fasta for cram testing [ 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] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[2] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] input[3] = false //save_unaligned input[4] = true //sort """ @@ -516,14 +482,16 @@ nextflow_process { { assert process.success }, { assert snapshot( file(process.out.cram[0][1]).name, - file(process.out.crai[0][1]).name + file(process.out.crai[0][1]).name, + cram(process.out.cram[0][1], process.out.cram[0][0].fasta ).getStatistics(exclude:["sorted"]), + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } } - test("sarscov2 - [fastq1, fastq2], index, fasta, false, false - stub") { + test("sarscov2 - [fastq1, fastq2], index, fasta_fai, false, false - stub") { options "-stub" setup { @@ -551,7 +519,10 @@ nextflow_process { ] ] input[1] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[2] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] input[3] = false //save_unaligned input[4] = false //sort """ @@ -573,7 +544,7 @@ nextflow_process { } - test("sarscov2 - fastq, index, fasta, true, false - stub") { + test("sarscov2 - fastq, index, fasta_fai, true, false - stub") { options "-stub" setup { @@ -598,8 +569,11 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] input[1] = BOWTIE2_BUILD.out.index - input[2] = [[ id:'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] - input[3] = false //save_unaligned + input[2] = [ + [ id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[3] = true //save_unaligned input[4] = false //sort """ } diff --git a/modules/nf-core/bowtie2/align/tests/main.nf.test.snap b/modules/nf-core/bowtie2/align/tests/main.nf.test.snap index b1df41e7..ac9f561d 100644 --- a/modules/nf-core/bowtie2/align/tests/main.nf.test.snap +++ b/modules/nf-core/bowtie2/align/tests/main.nf.test.snap @@ -1,7 +1,17 @@ { - "sarscov2 - [fastq1, fastq2], large_index, fasta, false, false - bam": { + "sarscov2 - [fastq1, fastq2], index, fasta_fai, true, true - bam": { "content": [ "test.bam", + { + "maxReadLength": 151, + "minReadLength": 53, + "meanReadLength": 138, + "maxQuality": 42, + "minQuality": 0, + "meanQuality": 41, + "readCount": 200, + "duplicateReadCount": 0 + }, [ [ { @@ -11,59 +21,17 @@ "test.bowtie2.log:md5,bd89ce1b28c93bf822bae391ffcedd19" ] ], - [ - - ], - { - "versions_bowtie2": [ - [ - "BOWTIE2_ALIGN", - "bowtie2", - "2.5.4" - ] - ], - "versions_pigz": [ - [ - "BOWTIE2_ALIGN", - "pigz", - "2.8" - ] - ], - "versions_samtools": [ - [ - "BOWTIE2_ALIGN", - "samtools", - "1.21" - ] - ] - } - ], - "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.3" - }, - "timestamp": "2026-02-03T15:18:12.706444258" - }, - "sarscov2 - fastq, index, fasta, false, false - sam2": { - "content": [ - [ - "ERR5069949.2151832\t16\tMT192765.1\t17453\t42\t150M\t*\t0\t0\tACGCACATTGCTAACTAAGGGCACACTAGAACCAGAATATTTCAATTCAGTGTGTAGACTTATGAAAACTATAGGTCCAGACATGTTCCTCGGAACTTGTCGGCGTTGTCCTGCTGAAATTGTTGACACTGTGAGTGCTTTGGTTTATGA\tAAAA&1 | sed -n "s/^Version: //p"'), topic: versions, emit: versions_bwa @@ -36,6 +37,15 @@ process BWA_MEM { "bam" def reference = fasta && extension=="cram" ? "--reference ${fasta}" : "" if (!fasta && extension=="cram") error "Fasta reference is required for CRAM output" + // + // For SAM output we can skip samtools view + // + def pipe_command = "" + if (extension == "sam") { + pipe_command = "> ${prefix}.${extension}" + } else { + pipe_command = "| samtools $samtools_command $args2 ${reference} --threads $task.cpus -o ${prefix}.${extension} -" + } """ INDEX=`find -L ./ -name "*.amb" | sed 's/\\.amb\$//'` @@ -44,7 +54,7 @@ process BWA_MEM { -t $task.cpus \\ \$INDEX \\ $reads \\ - | samtools $samtools_command $args2 ${reference} --threads $task.cpus -o ${prefix}.${extension} - + $pipe_command """ stub: diff --git a/modules/nf-core/bwa/mem/meta.yml b/modules/nf-core/bwa/mem/meta.yml index 450a3fe9..1c4ee883 100644 --- a/modules/nf-core/bwa/mem/meta.yml +++ b/modules/nf-core/bwa/mem/meta.yml @@ -81,6 +81,16 @@ output: pattern: "*.{cram}" ontologies: - edam: "http://edamontology.org/format_3462" + sam: + - - meta: + type: map + description: Groovy Map containing sample information + - "*.sam": + type: file + description: Output SAM file containing read alignments + pattern: "*.{sam}" + ontologies: + - edam: "http://edamontology.org/format_2573" csi: - - meta: type: map diff --git a/modules/nf-core/bwa/mem/tests/main.nf.test b/modules/nf-core/bwa/mem/tests/main.nf.test index 6486ab00..e284e2ea 100644 --- a/modules/nf-core/bwa/mem/tests/main.nf.test +++ b/modules/nf-core/bwa/mem/tests/main.nf.test @@ -46,6 +46,7 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.cram, + process.out.sam, process.out.csi, process.out.crai, process.out.findAll { key, val -> key.startsWith("versions") }, @@ -80,6 +81,7 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.cram, + process.out.sam, process.out.csi, process.out.crai, process.out.findAll { key, val -> key.startsWith("versions") }, @@ -91,6 +93,47 @@ nextflow_process { } + test("Single-End - SAM output") { + + config "./nextflow_sam.config" + + when { + params { + module_args2 = "--output-fmt sam" + } + + 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[1] = BWA_INDEX.out.index + input[2] = [[id: 'test'],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] + input[3] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.cram, + process.out.csi, + process.out.crai, + process.out.findAll { key, val -> key.startsWith("versions") }, + bam(process.out.sam[0][1]).getReadsMD5() + ).match() + } + ) + } + + } + test("Paired-End") { when { @@ -115,6 +158,7 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.cram, + process.out.sam, process.out.csi, process.out.crai, process.out.findAll { key, val -> key.startsWith("versions") }, @@ -150,6 +194,7 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.cram, + process.out.sam, process.out.csi, process.out.crai, process.out.findAll { key, val -> key.startsWith("versions") }, @@ -185,6 +230,7 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.cram, + process.out.sam, process.out.csi, process.out.crai, process.out.findAll { key, val -> key.startsWith("versions") }, @@ -196,6 +242,48 @@ nextflow_process { } + test ("Paired-end - SAM output") { + + config "./nextflow_sam.config" + + when { + params { + module_args2 = "--output-fmt sam" + } + + 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[1] = BWA_INDEX.out.index + input[2] = [[:],[]] + input[3] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.cram, + process.out.csi, + process.out.crai, + process.out.findAll { key, val -> key.startsWith("versions") }, + bam(process.out.sam[0][1]).getReadsMD5() + ).match() + } + ) + } + + } + test("Single-end - stub") { options "-stub" diff --git a/modules/nf-core/bwa/mem/tests/main.nf.test.snap b/modules/nf-core/bwa/mem/tests/main.nf.test.snap index 8aca4b23..6f9031d8 100644 --- a/modules/nf-core/bwa/mem/tests/main.nf.test.snap +++ b/modules/nf-core/bwa/mem/tests/main.nf.test.snap @@ -1,4 +1,42 @@ { + "Single-End - SAM output": { + "content": [ + [ + + ], + [ + + ], + [ + + ], + [ + + ], + { + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] + ] + }, + "798439cbd7fd81cbcc5078022dc5479d" + ], + "timestamp": "2026-05-11T12:09:32.334359515", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, "Single-End": { "content": [ [ @@ -9,6 +47,9 @@ ], [ + ], + [ + ], { "versions_bwa": [ @@ -28,10 +69,10 @@ }, "798439cbd7fd81cbcc5078022dc5479d" ], - "timestamp": "2026-02-18T12:42:52.901827", + "timestamp": "2026-05-11T12:07:21.233636979", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.10.4" + "nf-test": "0.9.5", + "nextflow": "26.04.0" } }, "Single-End Sort": { @@ -44,6 +85,9 @@ ], [ + ], + [ + ], { "versions_bwa": [ @@ -63,10 +107,10 @@ }, "94fcf617f5b994584c4e8d4044e16b4f" ], - "timestamp": "2026-02-18T12:43:01.149915", + "timestamp": "2026-05-11T12:07:28.74614221", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.10.4" + "nf-test": "0.9.5", + "nextflow": "26.04.0" } }, "Paired-End": { @@ -79,6 +123,9 @@ ], [ + ], + [ + ], { "versions_bwa": [ @@ -98,10 +145,10 @@ }, "57aeef88ed701a8ebc8e2f0a381b2a6" ], - "timestamp": "2026-02-18T12:43:09.528042", + "timestamp": "2026-05-11T12:07:42.612131595", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.10.4" + "nf-test": "0.9.5", + "nextflow": "26.04.0" } }, "Paired-End Sort": { @@ -114,6 +161,9 @@ ], [ + ], + [ + ], { "versions_bwa": [ @@ -133,10 +183,10 @@ }, "af8628d9df18b2d3d4f6fd47ef2bb872" ], - "timestamp": "2026-02-18T12:43:17.876121", + "timestamp": "2026-05-11T12:09:45.938323098", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.10.4" + "nf-test": "0.9.5", + "nextflow": "26.04.0" } }, "Single-end - stub": { @@ -155,6 +205,9 @@ ], "2": [ + + ], + "3": [ [ { "id": "test", @@ -163,7 +216,7 @@ "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "3": [ + "4": [ [ { "id": "test", @@ -172,14 +225,14 @@ "test.crai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "4": [ + "5": [ [ "BWA_MEM", "bwa", "0.7.19-r1273" ] ], - "5": [ + "6": [ [ "BWA_MEM", "samtools", @@ -215,6 +268,9 @@ }, "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] + ], + "sam": [ + ], "versions_bwa": [ [ @@ -232,10 +288,10 @@ ] } ], - "timestamp": "2026-02-18T12:43:33.853248", + "timestamp": "2026-05-11T12:10:09.92486753", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.10.4" + "nf-test": "0.9.5", + "nextflow": "26.04.0" } }, "Paired-End - no fasta": { @@ -248,6 +304,9 @@ ], [ + ], + [ + ], { "versions_bwa": [ @@ -267,10 +326,48 @@ }, "57aeef88ed701a8ebc8e2f0a381b2a6" ], - "timestamp": "2026-02-18T12:43:26.121474", + "timestamp": "2026-05-11T12:09:52.820539909", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.10.4" + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "Paired-end - SAM output": { + "content": [ + [ + + ], + [ + + ], + [ + + ], + [ + + ], + { + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] + ] + }, + "57aeef88ed701a8ebc8e2f0a381b2a6" + ], + "timestamp": "2026-05-11T12:10:00.199968933", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" } }, "Paired-end - stub": { @@ -289,6 +386,9 @@ ], "2": [ + + ], + "3": [ [ { "id": "test", @@ -297,7 +397,7 @@ "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "3": [ + "4": [ [ { "id": "test", @@ -306,14 +406,14 @@ "test.crai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "4": [ + "5": [ [ "BWA_MEM", "bwa", "0.7.19-r1273" ] ], - "5": [ + "6": [ [ "BWA_MEM", "samtools", @@ -349,6 +449,9 @@ }, "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] + ], + "sam": [ + ], "versions_bwa": [ [ @@ -366,10 +469,10 @@ ] } ], - "timestamp": "2026-02-18T12:43:42.119907", + "timestamp": "2026-05-11T12:10:16.940291647", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.10.4" + "nf-test": "0.9.5", + "nextflow": "26.04.0" } } } \ No newline at end of file diff --git a/modules/nf-core/bwa/mem/tests/nextflow_sam.config b/modules/nf-core/bwa/mem/tests/nextflow_sam.config new file mode 100644 index 00000000..831332e7 --- /dev/null +++ b/modules/nf-core/bwa/mem/tests/nextflow_sam.config @@ -0,0 +1,5 @@ +process { + withName: BWA_MEM { + ext.args2 = params.module_args2 + } +} diff --git a/modules/nf-core/chromap/chromap/environment.yml b/modules/nf-core/chromap/chromap/environment.yml index ee8f77a8..4447b170 100644 --- a/modules/nf-core/chromap/chromap/environment.yml +++ b/modules/nf-core/chromap/chromap/environment.yml @@ -4,5 +4,5 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::chromap=0.2.6 - - bioconda::samtools=1.20 + - bioconda::chromap=0.3.2 + - bioconda::samtools=1.23.1 diff --git a/modules/nf-core/chromap/chromap/main.nf b/modules/nf-core/chromap/chromap/main.nf index 61701f2e..ec3b8eec 100644 --- a/modules/nf-core/chromap/chromap/main.nf +++ b/modules/nf-core/chromap/chromap/main.nf @@ -3,9 +3,9 @@ process CHROMAP_CHROMAP { label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mulled-v2-1f09f39f20b1c4ee36581dc81cc323c70e661633:6500f0fa0c9536821177168555632d9811670937-0' : - 'biocontainers/mulled-v2-1f09f39f20b1c4ee36581dc81cc323c70e661633:6500f0fa0c9536821177168555632d9811670937-0' }" + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/5d/5d39e0b3f00c5469ffc2ceef4bd76959fba6313064ed2408dd4ccac498022ad6/data' : + 'community.wave.seqera.io/library/chromap_samtools:b975c17adf0096ba' }" input: tuple val(meta), path(reads) @@ -21,7 +21,8 @@ process CHROMAP_CHROMAP { tuple val(meta), path("*.bam") , optional:true, emit: bam tuple val(meta), path("*.tagAlign.gz"), optional:true, emit: tagAlign tuple val(meta), path("*.pairs.gz") , optional:true, emit: pairs - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('chromap'), eval("chromap --version 2>&1"), topic: versions, emit: versions_chromap + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools when: task.ext.when == null || task.ext.when @@ -29,7 +30,6 @@ process CHROMAP_CHROMAP { script: def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' - def args3 = task.ext.args3 ?: '' def prefix = task.ext.prefix ?: "${meta.id}" def args_list = args.tokenize() @@ -50,10 +50,8 @@ process CHROMAP_CHROMAP { def compression_cmds = "gzip -n ${prefix}.${file_extension}" if (args.contains("--SAM")) { compression_cmds = """ - samtools addreplacerg $args3 -o ${prefix}.rg.${file_extension} ${prefix}.${file_extension} samtools view $args2 -@ $task.cpus -bh \\ - -o ${prefix}.bam ${prefix}.rg.${file_extension} - rm ${prefix}.rg.${file_extension} + -o ${prefix}.bam ${prefix}.${file_extension} rm ${prefix}.${file_extension} """ } @@ -66,14 +64,8 @@ process CHROMAP_CHROMAP { -r $fasta \\ -1 ${reads.join(',')} \\ -o ${prefix}.${file_extension} - - $compression_cmds - cat <<-END_VERSIONS > versions.yml - "${task.process}": - chromap: \$(echo \$(chromap --version 2>&1)) - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS + $compression_cmds """ } else { """ @@ -87,12 +79,6 @@ process CHROMAP_CHROMAP { -o ${prefix}.${file_extension} $compression_cmds - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - chromap: \$(echo \$(chromap --version 2>&1)) - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } @@ -103,11 +89,5 @@ process CHROMAP_CHROMAP { touch ${prefix}.bam echo "" | gzip > ${prefix}.tagAlign.gz echo "" | gzip > ${prefix}.pairs.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - chromap: \$(echo \$(chromap --version 2>&1)) - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/chromap/chromap/meta.yml b/modules/nf-core/chromap/chromap/meta.yml index f9ec083e..5e024f17 100644 --- a/modules/nf-core/chromap/chromap/meta.yml +++ b/modules/nf-core/chromap/chromap/meta.yml @@ -1,7 +1,6 @@ name: chromap_chromap description: | - Performs preprocessing and alignment of chromatin fastq files to - fasta reference files using chromap. + Performs preprocessing and alignment of chromatin fastq files to fasta reference files using chromap. keywords: - chromap - alignment @@ -16,7 +15,8 @@ keywords: - duplicate removal tools: - chromap: - description: Fast alignment and preprocessing of chromatin profiles + description: | + Fast alignment and preprocessing of chromatin profiles homepage: https://github.com/haowenz/chromap documentation: https://github.com/haowenz/chromap tool_dev_url: https://github.com/haowenz/chromap @@ -41,9 +41,10 @@ input: e.g. [ id:'test' ] - fasta: type: file - description: | - The fasta reference file. - ontologies: [] + description: Reference genome FASTA file + pattern: "*.{fa,fasta,fna}" + ontologies: + - edam: "http://edamontology.org/format_1929" - - meta3: type: map description: | @@ -122,13 +123,46 @@ output: pattern: "*.pairs.gz" ontologies: - edam: http://edamontology.org/format_3989 # GZIP format + versions_chromap: + - - ${task.process}: + type: string + description: The name of the process + - chromap: + type: string + description: The name of the tool + - chromap --version 2>&1: + type: eval + description: The expression to obtain the version of the tool + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;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 name of the process + - chromap: + type: string + description: The name of the tool + - chromap --version 2>&1: + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool authors: - "@mahesh-panchal" - "@joseespinosa" diff --git a/modules/nf-core/chromap/chromap/tests/main.nf.test b/modules/nf-core/chromap/chromap/tests/main.nf.test index 1b0dcdcb..913b5a4b 100644 --- a/modules/nf-core/chromap/chromap/tests/main.nf.test +++ b/modules/nf-core/chromap/chromap/tests/main.nf.test @@ -57,7 +57,7 @@ nextflow_process { } } - test("sarscov2 - paired_end ") { + test("sarscov2 - paired_end") { when { process { diff --git a/modules/nf-core/chromap/chromap/tests/main.nf.test.snap b/modules/nf-core/chromap/chromap/tests/main.nf.test.snap index 1f06dc9e..deba8bcf 100644 --- a/modules/nf-core/chromap/chromap/tests/main.nf.test.snap +++ b/modules/nf-core/chromap/chromap/tests/main.nf.test.snap @@ -21,7 +21,18 @@ ], "4": [ - "versions.yml:md5,e3ece11a3651bd28b0ea714f94f09da7" + [ + "CHROMAP_CHROMAP", + "chromap", + "0.3.2-r518" + ] + ], + "5": [ + [ + "CHROMAP_CHROMAP", + "samtools", + "1.23.1" + ] ], "bam": [ @@ -41,16 +52,27 @@ "tagAlign": [ ], - "versions": [ - "versions.yml:md5,e3ece11a3651bd28b0ea714f94f09da7" + "versions_chromap": [ + [ + "CHROMAP_CHROMAP", + "chromap", + "0.3.2-r518" + ] + ], + "versions_samtools": [ + [ + "CHROMAP_CHROMAP", + "samtools", + "1.23.1" + ] ] } ], + "timestamp": "2026-03-27T17:32:15.943898", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" - }, - "timestamp": "2024-08-05T17:49:22.798324749" + "nf-test": "0.9.3", + "nextflow": "25.10.4" + } }, "sarscov2 - paired_end ": { "content": [ @@ -74,7 +96,18 @@ ], "4": [ - "versions.yml:md5,e3ece11a3651bd28b0ea714f94f09da7" + [ + "CHROMAP_CHROMAP", + "chromap", + "0.3.2-r518" + ] + ], + "5": [ + [ + "CHROMAP_CHROMAP", + "samtools", + "1.23.1" + ] ], "bam": [ @@ -94,16 +127,27 @@ "tagAlign": [ ], - "versions": [ - "versions.yml:md5,e3ece11a3651bd28b0ea714f94f09da7" + "versions_chromap": [ + [ + "CHROMAP_CHROMAP", + "chromap", + "0.3.2-r518" + ] + ], + "versions_samtools": [ + [ + "CHROMAP_CHROMAP", + "samtools", + "1.23.1" + ] ] } ], + "timestamp": "2026-03-27T17:32:51.441586", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" - }, - "timestamp": "2024-08-05T17:49:29.530097947" + "nf-test": "0.9.3", + "nextflow": "25.10.4" + } }, "sarscov2 - single_end - stub": { "content": [ @@ -145,7 +189,18 @@ ] ], "4": [ - "versions.yml:md5,e3ece11a3651bd28b0ea714f94f09da7" + [ + "CHROMAP_CHROMAP", + "chromap", + "0.3.2-r518" + ] + ], + "5": [ + [ + "CHROMAP_CHROMAP", + "samtools", + "1.23.1" + ] ], "bam": [ [ @@ -183,15 +238,101 @@ "test.tagAlign.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,e3ece11a3651bd28b0ea714f94f09da7" + "versions_chromap": [ + [ + "CHROMAP_CHROMAP", + "chromap", + "0.3.2-r518" + ] + ], + "versions_samtools": [ + [ + "CHROMAP_CHROMAP", + "samtools", + "1.23.1" + ] + ] + } + ], + "timestamp": "2026-03-27T17:33:28.468564", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + } + }, + "sarscov2 - paired_end": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed.gz:md5,f658c1e94adef751ad08e132aac92712" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + + ], + "4": [ + [ + "CHROMAP_CHROMAP", + "chromap", + "0.3.2-r518" + ] + ], + "5": [ + [ + "CHROMAP_CHROMAP", + "samtools", + "1.23.1" + ] + ], + "bam": [ + + ], + "bed": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed.gz:md5,f658c1e94adef751ad08e132aac92712" + ] + ], + "pairs": [ + + ], + "tagAlign": [ + + ], + "versions_chromap": [ + [ + "CHROMAP_CHROMAP", + "chromap", + "0.3.2-r518" + ] + ], + "versions_samtools": [ + [ + "CHROMAP_CHROMAP", + "samtools", + "1.23.1" + ] ] } ], + "timestamp": "2026-04-01T22:26:29.768814", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.3" - }, - "timestamp": "2024-08-05T17:49:42.086410229" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/picard/addorreplacereadgroups/environment.yml b/modules/nf-core/picard/addorreplacereadgroups/environment.yml new file mode 100644 index 00000000..b4ac4fe0 --- /dev/null +++ b/modules/nf-core/picard/addorreplacereadgroups/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + # renovate: datasource=conda depName=bioconda/picard + - bioconda::picard=3.4.0 diff --git a/modules/nf-core/picard/addorreplacereadgroups/main.nf b/modules/nf-core/picard/addorreplacereadgroups/main.nf new file mode 100644 index 00000000..0a323ed6 --- /dev/null +++ b/modules/nf-core/picard/addorreplacereadgroups/main.nf @@ -0,0 +1,58 @@ +process PICARD_ADDORREPLACEREADGROUPS { + tag "${meta.id}" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" + + input: + tuple val(meta), path(reads) + tuple val(meta2), path(fasta), path(fai) + + output: + tuple val(meta), path("*.bam"), emit: bam, optional: true + tuple val(meta), path("*.bai"), emit: bai, optional: true + tuple val(meta), path("*.cram"), emit: cram, optional: true + tuple val("${task.process}"), val('picard'), eval("picard AddOrReplaceReadGroups --version 2>&1 | sed -n 's/.*Version://p'"), topic: versions, emit: versions_picard + + 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 ?: "${reads.getExtension()}" + def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" + def avail_mem = 3072 + if (!task.memory) { + log.info('[Picard AddOrReplaceReadGroups] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() + } + + if ("${reads}" == "${prefix}.${suffix}") { + error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + } + """ + picard \\ + -Xmx${avail_mem}M \\ + AddOrReplaceReadGroups \\ + ${args} \\ + ${reference} \\ + --INPUT ${reads} \\ + --OUTPUT ${prefix}.${suffix} + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + def suffix = task.ext.suffix ?: "${reads.getExtension()}" + if ("${reads}" == "${prefix}.${suffix}") { + error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + } + """ + touch ${prefix}.${suffix} + """ +} diff --git a/modules/nf-core/picard/addorreplacereadgroups/meta.yml b/modules/nf-core/picard/addorreplacereadgroups/meta.yml new file mode 100644 index 00000000..907c401d --- /dev/null +++ b/modules/nf-core/picard/addorreplacereadgroups/meta.yml @@ -0,0 +1,111 @@ +name: picard_addorreplacereadgroups +description: Assigns all the reads in a file to a single new read-group +keywords: + - add + - replace + - read-group + - picard +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://gatk.broadinstitute.org/hc/en-us/articles/360037226472-AddOrReplaceReadGroups-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:'test', single_end:false ] + - reads: + type: file + description: Sequence reads file, can be SAM/BAM/CRAM format + pattern: "*.{bam,cram,sam}" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - fasta: + type: file + description: Reference genome file + pattern: "*.{fasta,fa,fasta.gz,fa.gz}" + ontologies: [] + - fai: + type: file + description: Reference genome index file + pattern: "*.{fai,fasta.fai,fa.fai,fasta.gz.fai,fa.gz.fai}" + ontologies: [] +output: + bam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.bam": + type: file + description: Output BAM file + pattern: "*.{bam}" + ontologies: [] + bai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.bai": + type: file + description: An optional BAM index file + pattern: "*.{bai}" + ontologies: [] + cram: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.cram": + type: file + description: Output CRAM file + pattern: "*.{cram}" + ontologies: [] + versions_picard: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard AddOrReplaceReadGroups --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard AddOrReplaceReadGroups --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool + +authors: + - "@sateeshperi" + - "@mjcipriano" + - "@hseabolt" + - "@cmatKhan" + - "@muffato" +maintainers: + - "@sateeshperi" + - "@mjcipriano" + - "@hseabolt" + - "@cmatKhan" + - "@muffato" diff --git a/modules/nf-core/picard/addorreplacereadgroups/tests/bam.config b/modules/nf-core/picard/addorreplacereadgroups/tests/bam.config new file mode 100644 index 00000000..132cc0f7 --- /dev/null +++ b/modules/nf-core/picard/addorreplacereadgroups/tests/bam.config @@ -0,0 +1,12 @@ +process { + withName: 'PICARD_ADDORREPLACEREADGROUPS'{ + ext.prefix = { "${meta.id}.replaced"} + ext.args = {[ + "--CREATE_INDEX", + "-LB ${meta.id}", + "-PL ILLUMINA", + "-PU bc1", + "-SM ${meta.id}" + ].join(' ').trim()} + } +} diff --git a/modules/nf-core/picard/addorreplacereadgroups/tests/cram.config b/modules/nf-core/picard/addorreplacereadgroups/tests/cram.config new file mode 100644 index 00000000..be92e72b --- /dev/null +++ b/modules/nf-core/picard/addorreplacereadgroups/tests/cram.config @@ -0,0 +1,12 @@ +process { + withName: 'PICARD_ADDORREPLACEREADGROUPS'{ + ext.prefix = { "${meta.id}.replaced"} + ext.args = {[ + "-LB ${meta.id}", + "-PL ILLUMINA", + "-PU bc1", + "-SM ${meta.id}" + ].join(' ').trim()} + ext.suffix = { "cram" } + } +} diff --git a/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test b/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test new file mode 100644 index 00000000..78565882 --- /dev/null +++ b/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test @@ -0,0 +1,83 @@ + +nextflow_process { + + name "Test Process PICARD_ADDORREPLACEREADGROUPS" + script "../main.nf" + process "PICARD_ADDORREPLACEREADGROUPS" + + tag "modules" + tag "modules_nfcore" + tag "picard" + tag "picard/addorreplacereadgroups" + + test("sarscov2 - bam") { + config "./bam.config" + + when { + process { + """ + input[0] = [ [:], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) ] + input[1] = [ [:], [], [] ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.bam[0][1]).name, + file(process.out.bai[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + test("homo_sapiens - cram") { + config "./cram.config" + + when { + process { + """ + input[0] = [ + [ id:'test' ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), ] + ] + input[1] = [ [:], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.cram[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + test("sarscov2 - bam - stub") { + config "./bam.config" + options "-stub" + when { + process { + """ + input[0] = [ [:], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) ] + input[1] = [ [:], [], [] ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } +} diff --git a/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test.snap b/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test.snap new file mode 100644 index 00000000..17295697 --- /dev/null +++ b/modules/nf-core/picard/addorreplacereadgroups/tests/main.nf.test.snap @@ -0,0 +1,73 @@ +{ + "homo_sapiens - cram": { + "content": [ + "test.replaced.cram", + { + "versions_picard": [ + [ + "PICARD_ADDORREPLACEREADGROUPS", + "picard", + "3.4.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-02-02T09:36:16.966842212" + }, + "sarscov2 - bam - stub": { + "content": [ + { + "bai": [ + + ], + "bam": [ + [ + { + + }, + "null.replaced.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "cram": [ + + ], + "versions_picard": [ + [ + "PICARD_ADDORREPLACEREADGROUPS", + "picard", + "3.4.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + }, + "timestamp": "2026-02-19T17:34:40.3572859" + }, + "sarscov2 - bam": { + "content": [ + "null.replaced.bam", + "null.replaced.bai", + { + "versions_picard": [ + [ + "PICARD_ADDORREPLACEREADGROUPS", + "picard", + "3.4.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-02-02T09:36:00.935196996" + } +} \ No newline at end of file diff --git a/modules/nf-core/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf index 17bcf27b..36afba6f 100644 --- a/modules/nf-core/picard/markduplicates/main.nf +++ b/modules/nf-core/picard/markduplicates/main.nf @@ -3,14 +3,13 @@ process PICARD_MARKDUPLICATES { label 'process_medium' conda "${moduleDir}/environment.yml" - container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: tuple val(meta), path(reads) - tuple val(meta2), path(fasta) - tuple val(meta3), path(fai) + tuple val(meta2), path(fasta), path(fai) output: tuple val(meta), path("*.bam"), emit: bam, optional: true diff --git a/modules/nf-core/picard/markduplicates/meta.yml b/modules/nf-core/picard/markduplicates/meta.yml index aa0ddbdb..cf95a0c5 100644 --- a/modules/nf-core/picard/markduplicates/meta.yml +++ b/modules/nf-core/picard/markduplicates/meta.yml @@ -37,11 +37,6 @@ input: description: Reference genome fasta file, required for CRAM input pattern: "*.{fasta,fa}" ontologies: [] - - - meta3: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'genome' ] - fai: type: file description: Reference genome fasta index diff --git a/modules/nf-core/picard/markduplicates/tests/main.nf.test b/modules/nf-core/picard/markduplicates/tests/main.nf.test index 4d006453..227bfc84 100644 --- a/modules/nf-core/picard/markduplicates/tests/main.nf.test +++ b/modules/nf-core/picard/markduplicates/tests/main.nf.test @@ -18,8 +18,7 @@ nextflow_process { [ id:'test', single_end:false ], // meta map file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) ]) - input[1] = [ [:], [] ] - input[2] = [ [:], [] ] + input[1] = [ [:], [], [] ] """ } } @@ -45,8 +44,7 @@ nextflow_process { [ id:'test', single_end:false ], // meta map file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) ]) - input[1] = [ [:], [] ] - input[2] = [ [:], [] ] + input[1] = [ [:], [], [] ] """ } } @@ -74,10 +72,7 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ]) """ @@ -105,8 +100,7 @@ nextflow_process { [ id:'test', single_end:false ], // meta map file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) ]) - input[1] = [ [:], [] ] - input[2] = [ [:], [] ] + input[1] = [ [:], [], [] ] """ } } @@ -128,8 +122,7 @@ nextflow_process { [ id:'test', single_end:false ], // meta map file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) ]) - input[1] = [ [:], [] ] - input[2] = [ [:], [] ] + input[1] = [ [:], [], [] ] """ } } @@ -153,10 +146,7 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ]) """ diff --git a/modules/nf-core/picard/markduplicates/tests/main.nf.test.snap b/modules/nf-core/picard/markduplicates/tests/main.nf.test.snap index 4ea479a3..261f1d5f 100644 --- a/modules/nf-core/picard/markduplicates/tests/main.nf.test.snap +++ b/modules/nf-core/picard/markduplicates/tests/main.nf.test.snap @@ -41,11 +41,11 @@ ] } ], - "timestamp": "2026-02-19T17:43:13.544887277", "meta": { "nf-test": "0.9.4", "nextflow": "25.10.4" - } + }, + "timestamp": "2026-02-19T17:43:13.544887277" }, "sarscov2 [unsorted bam] - stub": { "content": [ @@ -89,11 +89,11 @@ ] } ], - "timestamp": "2026-02-19T17:43:06.193033248", "meta": { "nf-test": "0.9.4", "nextflow": "25.10.4" - } + }, + "timestamp": "2026-02-19T17:43:06.193033248" }, "sarscov2 [unsorted bam]": { "content": [ @@ -113,11 +113,11 @@ ] } ], - "timestamp": "2026-02-19T17:42:40.574463587", "meta": { "nf-test": "0.9.4", "nextflow": "25.10.4" - } + }, + "timestamp": "2026-02-19T17:42:40.574463587" }, "sarscov2 [sorted bam]": { "content": [ @@ -137,11 +137,11 @@ ] } ], - "timestamp": "2026-02-19T17:42:49.374645492", "meta": { "nf-test": "0.9.4", "nextflow": "25.10.4" - } + }, + "timestamp": "2026-02-19T17:42:49.374645492" }, "homo_sapiens [cram]": { "content": [ @@ -161,11 +161,11 @@ ] } ], - "timestamp": "2026-02-19T17:42:59.07843756", "meta": { "nf-test": "0.9.4", "nextflow": "25.10.4" - } + }, + "timestamp": "2026-02-19T17:42:59.07843756" }, "homo_sapiens [cram] - stub": { "content": [ @@ -209,10 +209,10 @@ ] } ], - "timestamp": "2026-02-19T17:43:20.676018462", "meta": { "nf-test": "0.9.4", "nextflow": "25.10.4" - } + }, + "timestamp": "2026-02-19T17:43:20.676018462" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/flagstat/environment.yml b/modules/nf-core/samtools/flagstat/environment.yml index 89e12a64..946bb362 100644 --- a/modules/nf-core/samtools/flagstat/environment.yml +++ b/modules/nf-core/samtools/flagstat/environment.yml @@ -5,6 +5,6 @@ channels: - bioconda dependencies: # renovate: datasource=conda depName=bioconda/htslib - - bioconda::htslib=1.22.1 + - bioconda::htslib=1.23.1 # renovate: datasource=conda depName=bioconda/samtools - - bioconda::samtools=1.22.1 + - bioconda::samtools=1.23.1 diff --git a/modules/nf-core/samtools/flagstat/main.nf b/modules/nf-core/samtools/flagstat/main.nf index 0cfb7e87..2d9588b9 100644 --- a/modules/nf-core/samtools/flagstat/main.nf +++ b/modules/nf-core/samtools/flagstat/main.nf @@ -1,11 +1,11 @@ process SAMTOOLS_FLAGSTAT { - 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/samtools:1.22.1--h96c455f_0' : - 'biocontainers/samtools:1.22.1--h96c455f_0' }" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/8c/8c5d2818c8b9f58e1fba77ce219fdaf32087ae53e857c4a496402978af26e78c/data' + : 'community.wave.seqera.io/library/htslib_samtools:1.23.1--5b6bb4ede7e612e5'}" input: tuple val(meta), path(bam), path(bai) @@ -23,7 +23,7 @@ process SAMTOOLS_FLAGSTAT { samtools \\ flagstat \\ --threads ${task.cpus} \\ - $bam \\ + ${bam} \\ > ${prefix}.flagstat """ diff --git a/modules/nf-core/samtools/flagstat/meta.yml b/modules/nf-core/samtools/flagstat/meta.yml index 8caa1bcc..f658acdd 100644 --- a/modules/nf-core/samtools/flagstat/meta.yml +++ b/modules/nf-core/samtools/flagstat/meta.yml @@ -73,3 +73,4 @@ authors: - "@drpatelh" maintainers: - "@drpatelh" + - "@matthdsm" diff --git a/modules/nf-core/samtools/flagstat/tests/main.nf.test.snap b/modules/nf-core/samtools/flagstat/tests/main.nf.test.snap index f5c882da..b110c47c 100644 --- a/modules/nf-core/samtools/flagstat/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/flagstat/tests/main.nf.test.snap @@ -15,7 +15,7 @@ [ "SAMTOOLS_FLAGSTAT", "samtools", - "1.22.1" + "1.23.1" ] ], "flagstat": [ @@ -31,16 +31,16 @@ [ "SAMTOOLS_FLAGSTAT", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.3" + "nextflow": "25.10.4" }, - "timestamp": "2026-02-03T11:14:30.820969684" + "timestamp": "2026-03-19T08:59:26.188788" }, "BAM": { "content": [ @@ -58,7 +58,7 @@ [ "SAMTOOLS_FLAGSTAT", "samtools", - "1.22.1" + "1.23.1" ] ], "flagstat": [ @@ -74,15 +74,15 @@ [ "SAMTOOLS_FLAGSTAT", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.3" + "nextflow": "25.10.4" }, - "timestamp": "2026-02-03T11:14:25.581619424" + "timestamp": "2026-03-19T08:59:20.212002" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/idxstats/environment.yml b/modules/nf-core/samtools/idxstats/environment.yml index 89e12a64..946bb362 100644 --- a/modules/nf-core/samtools/idxstats/environment.yml +++ b/modules/nf-core/samtools/idxstats/environment.yml @@ -5,6 +5,6 @@ channels: - bioconda dependencies: # renovate: datasource=conda depName=bioconda/htslib - - bioconda::htslib=1.22.1 + - bioconda::htslib=1.23.1 # renovate: datasource=conda depName=bioconda/samtools - - bioconda::samtools=1.22.1 + - bioconda::samtools=1.23.1 diff --git a/modules/nf-core/samtools/idxstats/main.nf b/modules/nf-core/samtools/idxstats/main.nf index d5b70a7f..4d74768a 100644 --- a/modules/nf-core/samtools/idxstats/main.nf +++ b/modules/nf-core/samtools/idxstats/main.nf @@ -1,11 +1,11 @@ process SAMTOOLS_IDXSTATS { - 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/samtools:1.22.1--h96c455f_0' : - 'biocontainers/samtools:1.22.1--h96c455f_0' }" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/8c/8c5d2818c8b9f58e1fba77ce219fdaf32087ae53e857c4a496402978af26e78c/data' + : 'community.wave.seqera.io/library/htslib_samtools:1.23.1--5b6bb4ede7e612e5'}" input: tuple val(meta), path(bam), path(bai) @@ -24,8 +24,8 @@ process SAMTOOLS_IDXSTATS { # Note: --threads value represents *additional* CPUs to allocate (total CPUs = 1 + --threads). samtools \\ idxstats \\ - --threads ${task.cpus-1} \\ - $bam \\ + --threads ${task.cpus - 1} \\ + ${bam} \\ > ${prefix}.idxstats """ diff --git a/modules/nf-core/samtools/idxstats/meta.yml b/modules/nf-core/samtools/idxstats/meta.yml index fd153841..0f9fb3d7 100644 --- a/modules/nf-core/samtools/idxstats/meta.yml +++ b/modules/nf-core/samtools/idxstats/meta.yml @@ -73,3 +73,4 @@ authors: - "@drpatelh" maintainers: - "@drpatelh" + - "@matthdsm" diff --git a/modules/nf-core/samtools/idxstats/tests/main.nf.test.snap b/modules/nf-core/samtools/idxstats/tests/main.nf.test.snap index 19a54c7c..7bcde2fd 100644 --- a/modules/nf-core/samtools/idxstats/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/idxstats/tests/main.nf.test.snap @@ -15,16 +15,16 @@ [ "SAMTOOLS_IDXSTATS", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.3" + "nextflow": "25.10.4" }, - "timestamp": "2026-02-02T16:21:46.333090477" + "timestamp": "2026-03-19T08:59:41.877526" }, "bam": { "content": [ @@ -42,15 +42,15 @@ [ "SAMTOOLS_IDXSTATS", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.3" + "nextflow": "25.10.4" }, - "timestamp": "2026-02-02T16:21:41.063422521" + "timestamp": "2026-03-19T08:59:34.725514" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/index/environment.yml b/modules/nf-core/samtools/index/environment.yml index 89e12a64..946bb362 100644 --- a/modules/nf-core/samtools/index/environment.yml +++ b/modules/nf-core/samtools/index/environment.yml @@ -5,6 +5,6 @@ channels: - bioconda dependencies: # renovate: datasource=conda depName=bioconda/htslib - - bioconda::htslib=1.22.1 + - bioconda::htslib=1.23.1 # renovate: datasource=conda depName=bioconda/samtools - - bioconda::samtools=1.22.1 + - bioconda::samtools=1.23.1 diff --git a/modules/nf-core/samtools/index/main.nf b/modules/nf-core/samtools/index/main.nf index e2a0e56d..5b5756b1 100644 --- a/modules/nf-core/samtools/index/main.nf +++ b/modules/nf-core/samtools/index/main.nf @@ -1,19 +1,17 @@ process SAMTOOLS_INDEX { - 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/samtools:1.22.1--h96c455f_0' : - 'biocontainers/samtools:1.22.1--h96c455f_0' }" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/8c/8c5d2818c8b9f58e1fba77ce219fdaf32087ae53e857c4a496402978af26e78c/data' + : 'community.wave.seqera.io/library/htslib_samtools:1.23.1--5b6bb4ede7e612e5'}" input: tuple val(meta), path(input) output: - tuple val(meta), path("*.bai") , optional:true, emit: bai - tuple val(meta), path("*.csi") , optional:true, emit: csi - tuple val(meta), path("*.crai"), optional:true, emit: crai + tuple val(meta), path("*.{bai,csi,crai}"), emit: index tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), emit: versions_samtools, topic: versions when: @@ -25,14 +23,15 @@ process SAMTOOLS_INDEX { samtools \\ index \\ -@ ${task.cpus} \\ - $args \\ - $input + ${args} \\ + ${input} """ stub: def args = task.ext.args ?: '' - def extension = file(input).getExtension() == 'cram' ? - "crai" : args.contains("-c") ? "csi" : "bai" + def extension = file(input).getExtension() == 'cram' + ? "crai" + : args.contains("-c") ? "csi" : "bai" """ touch ${input}.${extension} """ diff --git a/modules/nf-core/samtools/index/meta.yml b/modules/nf-core/samtools/index/meta.yml index c6d4ce25..d4938bcd 100644 --- a/modules/nf-core/samtools/index/meta.yml +++ b/modules/nf-core/samtools/index/meta.yml @@ -28,38 +28,16 @@ input: description: input file ontologies: [] output: - bai: + index: - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.bai": + - "*.{bai,csi,crai}": type: file description: BAM/CRAM/SAM index file - pattern: "*.{bai,crai,sai}" - ontologies: [] - csi: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.csi": - type: file - description: CSI index file - pattern: "*.{csi}" - ontologies: [] - crai: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "*.crai": - type: file - description: BAM/CRAM/SAM index file - pattern: "*.{bai,crai,sai}" + pattern: "*.{bai,csi,crai}" ontologies: [] versions_samtools: - - ${task.process}: @@ -87,6 +65,6 @@ authors: - "@ewels" - "@maxulysse" maintainers: - - "@drpatelh" - "@ewels" - "@maxulysse" + - "@matthdsm" diff --git a/modules/nf-core/samtools/index/tests/csi.nextflow.config b/modules/nf-core/samtools/index/tests/csi.nextflow.config index 0ed260ef..4af6d82c 100644 --- a/modules/nf-core/samtools/index/tests/csi.nextflow.config +++ b/modules/nf-core/samtools/index/tests/csi.nextflow.config @@ -3,5 +3,4 @@ process { withName: SAMTOOLS_INDEX { ext.args = '-c' } - } diff --git a/modules/nf-core/samtools/index/tests/main.nf.test b/modules/nf-core/samtools/index/tests/main.nf.test index c96cec86..f9d39222 100644 --- a/modules/nf-core/samtools/index/tests/main.nf.test +++ b/modules/nf-core/samtools/index/tests/main.nf.test @@ -24,7 +24,7 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( - process.out.bai, + process.out.index, process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) @@ -47,7 +47,7 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( - process.out.crai, + process.out.index, process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) @@ -72,7 +72,7 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( - file(process.out.csi[0][1]).name, + file(process.out.index[0][1]).name, process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) @@ -96,7 +96,7 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( - process.out.bai, + process.out.index, process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) @@ -120,7 +120,7 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( - process.out.crai, + process.out.index, process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) @@ -146,7 +146,7 @@ nextflow_process { assertAll ( { assert process.success }, { assert snapshot( - process.out.csi, + process.out.index, process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) diff --git a/modules/nf-core/samtools/index/tests/main.nf.test.snap b/modules/nf-core/samtools/index/tests/main.nf.test.snap index afc8a1ff..337dec77 100644 --- a/modules/nf-core/samtools/index/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/index/tests/main.nf.test.snap @@ -15,16 +15,16 @@ [ "SAMTOOLS_INDEX", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.2" + "nextflow": "25.10.4" }, - "timestamp": "2026-01-28T17:52:10.030187" + "timestamp": "2026-03-19T09:00:39.171613" }, "crai - stub": { "content": [ @@ -42,16 +42,16 @@ [ "SAMTOOLS_INDEX", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.2" + "nextflow": "25.10.4" }, - "timestamp": "2026-01-28T17:51:59.125484" + "timestamp": "2026-03-19T09:00:32.838795" }, "bai - stub": { "content": [ @@ -69,16 +69,16 @@ [ "SAMTOOLS_INDEX", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.2" + "nextflow": "25.10.4" }, - "timestamp": "2026-01-28T17:51:47.277042" + "timestamp": "2026-03-19T09:00:25.255379" }, "csi": { "content": [ @@ -88,16 +88,16 @@ [ "SAMTOOLS_INDEX", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.2" + "nextflow": "25.10.4" }, - "timestamp": "2026-01-28T17:51:35.758735" + "timestamp": "2026-03-19T09:00:18.414839" }, "crai": { "content": [ @@ -115,16 +115,16 @@ [ "SAMTOOLS_INDEX", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.2" + "nextflow": "25.10.4" }, - "timestamp": "2026-01-28T17:51:26.561965" + "timestamp": "2026-03-19T09:00:13.571297" }, "bai": { "content": [ @@ -142,15 +142,15 @@ [ "SAMTOOLS_INDEX", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.2" + "nextflow": "25.10.4" }, - "timestamp": "2026-01-28T17:51:15.299035" + "timestamp": "2026-03-19T09:00:06.767362" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/sort/environment.yml b/modules/nf-core/samtools/sort/environment.yml index 89e12a64..946bb362 100644 --- a/modules/nf-core/samtools/sort/environment.yml +++ b/modules/nf-core/samtools/sort/environment.yml @@ -5,6 +5,6 @@ channels: - bioconda dependencies: # renovate: datasource=conda depName=bioconda/htslib - - bioconda::htslib=1.22.1 + - bioconda::htslib=1.23.1 # renovate: datasource=conda depName=bioconda/samtools - - bioconda::samtools=1.22.1 + - bioconda::samtools=1.23.1 diff --git a/modules/nf-core/samtools/sort/main.nf b/modules/nf-core/samtools/sort/main.nf index 6b5aa31d..e75ce915 100644 --- a/modules/nf-core/samtools/sort/main.nf +++ b/modules/nf-core/samtools/sort/main.nf @@ -1,24 +1,22 @@ process SAMTOOLS_SORT { - 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/samtools:1.22.1--h96c455f_0' : - 'biocontainers/samtools:1.22.1--h96c455f_0' }" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/8c/8c5d2818c8b9f58e1fba77ce219fdaf32087ae53e857c4a496402978af26e78c/data' + : 'community.wave.seqera.io/library/htslib_samtools:1.23.1--5b6bb4ede7e612e5'}" input: - tuple val(meta) , path(bam) - tuple val(meta2), path(fasta) + tuple val(meta), path(bam) + tuple val(meta2), path(fasta), path(fai) val index_format output: - tuple val(meta), path("${prefix}.bam"), emit: bam, optional: true - tuple val(meta), path("${prefix}.cram"), emit: cram, optional: true - tuple val(meta), path("${prefix}.sam"), emit: sam, optional: true - tuple val(meta), path("${prefix}.${extension}.crai"), emit: crai, optional: true - tuple val(meta), path("${prefix}.${extension}.csi"), emit: csi, optional: true - tuple val(meta), path("${prefix}.${extension}.bai"), emit: bai, optional: true + tuple val(meta), path("${prefix}.bam"), emit: bam, optional: true + tuple val(meta), path("${prefix}.cram"), emit: cram, optional: true + tuple val(meta), path("${prefix}.sam"), emit: sam, optional: true + tuple val(meta), path("${prefix}.${extension}.{crai,csi,bai}"), emit: index, optional: true tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools when: @@ -27,52 +25,73 @@ process SAMTOOLS_SORT { script: def args = task.ext.args ?: '' prefix = task.ext.prefix ?: "${meta.id}" - extension = args.contains("--output-fmt sam") ? "sam" : - args.contains("--output-fmt cram") ? "cram" : - "bam" + extension = args.contains("--output-fmt sam") + ? "sam" + : args.contains("--output-fmt cram") + ? "cram" + : "bam" def reference = fasta ? "--reference ${fasta}" : "" - output_file = index_format ? "${prefix}.${extension}##idx##${prefix}.${extension}.${index_format} --write-index" : "${prefix}.${extension}" + //setting default values + def write_index = "" + def output_file = "${prefix}.${extension}" + + // Update if index is requested + if (index_format != '' && index_format) { + write_index = "--write-index" + output_file = "${prefix}.${extension}##idx##${prefix}.${extension}.${index_format}" + } + def is_sam = (bam instanceof List ? bam[0] : bam).name.endsWith('.sam') if (index_format) { if (!index_format.matches('bai|csi|crai')) { - error "Index format not one of bai, csi, crai." - } else if (extension == "sam") { - error "Indexing not compatible with SAM output" + error("Index format not one of bai, csi, crai.") + } + else if (extension == "sam") { + error("Indexing not compatible with SAM output") } } - if ("$bam" == "${prefix}.bam") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + if ("${bam}" == "${prefix}.bam") { + error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + } + if ("${bam}" == "${prefix}.bam") { + error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + } + + def input_source = is_sam ? "${bam}" : "-" + def pre_command = is_sam ? "" : "samtools cat ${bam} | " """ - samtools cat \\ - ${bam} \\ - | \\ - samtools sort \\ - $args \\ + ${pre_command}samtools sort \\ + ${args} \\ -T ${prefix} \\ - --threads $task.cpus \\ + --threads ${task.cpus} \\ ${reference} \\ -o ${output_file} \\ - - - + ${write_index} \\ + ${input_source} """ stub: def args = task.ext.args ?: '' prefix = task.ext.prefix ?: "${meta.id}" - extension = args.contains("--output-fmt sam") ? "sam" : - args.contains("--output-fmt cram") ? "cram" : - "bam" + extension = args.contains("--output-fmt sam") + ? "sam" + : args.contains("--output-fmt cram") + ? "cram" + : "bam" + if (index_format) { if (!index_format.matches('bai|csi|crai')) { - error "Index format not one of bai, csi, crai." - } else if (extension == "sam") { - error "Indexing not compatible with SAM output" + error("Index format not one of bai, csi, crai.") + } + else if (extension == "sam") { + error("Indexing not compatible with SAM output") } } + index = index_format ? "touch ${prefix}.${extension}.${index_format}" : "" """ touch ${prefix}.${extension} ${index} - """ } diff --git a/modules/nf-core/samtools/sort/meta.yml b/modules/nf-core/samtools/sort/meta.yml index 69968304..0447a95e 100644 --- a/modules/nf-core/samtools/sort/meta.yml +++ b/modules/nf-core/samtools/sort/meta.yml @@ -38,6 +38,12 @@ input: pattern: "*.{fa,fasta,fna}" optional: true ontologies: [] + - fai: + type: file + description: Reference genome FASTA index file + pattern: "*.{fai}" + optional: true + ontologies: [] - index_format: type: string description: Index format to use (optional) @@ -76,38 +82,16 @@ output: description: Sorted SAM file pattern: "*.{sam}" ontologies: [] - crai: + index: - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "${prefix}.${extension}.crai": + - "${prefix}.${extension}.{crai,csi,bai}": type: file description: CRAM index file (optional) - pattern: "*.crai" - ontologies: [] - csi: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "${prefix}.${extension}.csi": - type: file - description: BAM index file (optional) - pattern: "*.csi" - ontologies: [] - bai: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - "${prefix}.${extension}.bai": - type: file - description: BAM index file (optional) - pattern: "*.bai" + pattern: "*.{crai,csi,bai}" ontologies: [] versions_samtools: - - ${task.process}: diff --git a/modules/nf-core/samtools/sort/tests/main.nf.test b/modules/nf-core/samtools/sort/tests/main.nf.test index df47bb25..b60edf8c 100644 --- a/modules/nf-core/samtools/sort/tests/main.nf.test +++ b/modules/nf-core/samtools/sort/tests/main.nf.test @@ -21,7 +21,8 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) input[2] = '' """ @@ -33,7 +34,7 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.bam, - process.out.bai, + process.out.index, process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) @@ -53,7 +54,8 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) input[2] = 'bai' """ @@ -65,7 +67,7 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.bam, - process.out.bai, + process.out.index, process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) @@ -85,7 +87,8 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) input[2] = 'csi' """ @@ -97,7 +100,7 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.bam, - process.out.csi, + process.out.index, process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) @@ -120,7 +123,8 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ]) input[2] = '' """ @@ -132,7 +136,7 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.bam, - process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.index.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) @@ -155,7 +159,8 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ]) input[2] = 'bai' """ @@ -167,7 +172,7 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.bam, - process.out.bai.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.index.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) @@ -190,7 +195,8 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ]) input[2] = 'csi' """ @@ -202,7 +208,7 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.bam, - process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.index.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) @@ -222,7 +228,8 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ]) input[2] = '' """ @@ -234,7 +241,7 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.cram.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.crai.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.index.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) @@ -255,7 +262,8 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) input[2] = '' """ @@ -286,7 +294,8 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ]) input[2] = '' """ @@ -315,7 +324,8 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ]) input[2] = '' """ @@ -329,4 +339,72 @@ nextflow_process { ) } } + + test("multi_sam") { + + config "./nextflow_sam.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pairtools/mock.sam', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'fasta' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ]) + input[2] = '' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.bam.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.index.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + + test("sam") { + + config "./nextflow_sam.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pairtools/mock.sam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/pairtools/mock.sam', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'fasta' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ]) + input[2] = '' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.bam.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.index.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } } diff --git a/modules/nf-core/samtools/sort/tests/main.nf.test.snap b/modules/nf-core/samtools/sort/tests/main.nf.test.snap index 4e618fa3..5ce05c3c 100644 --- a/modules/nf-core/samtools/sort/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/sort/tests/main.nf.test.snap @@ -24,16 +24,16 @@ [ "SAMTOOLS_SORT", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-10-29T12:47:01.171084" + "timestamp": "2026-03-19T09:04:36.491063" }, "bam_csi_index": { "content": [ @@ -43,7 +43,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,72ca1dff5344a5e5e6b892fe5f6b134d" + "test.sorted.bam:md5,53aea06779611856bc481c60beabecaa" ] ], [ @@ -52,7 +52,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam.csi:md5,01394e702c729cb478df914ffaf9f7f8" + "test.sorted.bam.csi:md5,f77a4adb3dde616d7eafd28db2ed147c" ] ], { @@ -60,16 +60,16 @@ [ "SAMTOOLS_SORT", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-10-29T12:46:00.961675" + "timestamp": "2026-03-19T09:04:14.341977" }, "bam - stub": { "content": [ @@ -78,16 +78,16 @@ [ "SAMTOOLS_SORT", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-10-29T12:47:12.154354" + "timestamp": "2026-03-19T09:04:43.558376" }, "multiple bam bai index": { "content": [ @@ -97,7 +97,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,3ffa2affc29f0aa6e7b36dded84625fe" + "test.sorted.bam:md5,a15f775c655d4a3b080812a8aae84d34" ] ], [ @@ -114,16 +114,16 @@ [ "SAMTOOLS_SORT", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-10-29T12:46:25.488622" + "timestamp": "2026-03-19T09:04:25.647565" }, "cram - stub": { "content": [ @@ -132,16 +132,16 @@ [ "SAMTOOLS_SORT", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-10-29T12:47:28.485045" + "timestamp": "2026-03-19T09:04:54.684578" }, "multiple bam": { "content": [ @@ -151,7 +151,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,cd4eb0077f25e9cff395366b8883dd1f" + "test.sorted.bam:md5,f4343475d9ed2c261f31e1e49d67c1b6" ] ], [ @@ -162,16 +162,16 @@ [ "SAMTOOLS_SORT", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-10-29T12:46:13.168476" + "timestamp": "2026-03-19T09:04:20.2368" }, "multiple bam - stub": { "content": [ @@ -180,16 +180,16 @@ [ "SAMTOOLS_SORT", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-10-29T12:47:21.628088" + "timestamp": "2026-03-19T09:04:48.874947" }, "bam_no_index": { "content": [ @@ -199,7 +199,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,26b27d1f9bcb61c25da21b562349784e" + "test.sorted.bam:md5,9277ba4bea590ae1b84e6ab06d11d79b" ] ], [ @@ -210,16 +210,40 @@ [ "SAMTOOLS_SORT", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-10-29T12:45:47.139418" + "timestamp": "2026-03-19T09:04:03.721646" + }, + "multi_sam": { + "content": [ + [ + + ], + [ + + ], + { + "versions_samtools": [ + [ + "SAMTOOLS_SORT", + "samtools", + "1.23.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-03-19T09:05:00.624092" }, "multiple bam csi index": { "content": [ @@ -229,7 +253,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,295503ba5342531a3310c33ad0efbc22" + "test.sorted.bam:md5,f168809dc154156c40548c06d0f46791" ] ], [ @@ -246,16 +270,40 @@ [ "SAMTOOLS_SORT", "samtools", - "1.22.1" + "1.23.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-03-19T09:04:31.11865" + }, + "sam": { + "content": [ + [ + + ], + [ + + ], + { + "versions_samtools": [ + [ + "SAMTOOLS_SORT", + "samtools", + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-10-29T12:46:51.5531" + "timestamp": "2026-03-19T09:05:06.309319" }, "bam_bai_index": { "content": [ @@ -265,7 +313,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,cae7564cb83bb4a5911205bf94124b54" + "test.sorted.bam:md5,2ca2d7f2368251d3f06f84afa49865a5" ] ], [ @@ -274,7 +322,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam.bai:md5,50dd467c169545a4d5d1f709f7e986e0" + "test.sorted.bam.bai:md5,66dca3dc2e314029035799f6f44f60d1" ] ], { @@ -282,15 +330,15 @@ [ "SAMTOOLS_SORT", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-10-29T12:45:52.796936" + "timestamp": "2026-03-19T09:04:09.147615" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/sort/tests/nextflow.config b/modules/nf-core/samtools/sort/tests/nextflow.config index 723f62b2..ca694caa 100644 --- a/modules/nf-core/samtools/sort/tests/nextflow.config +++ b/modules/nf-core/samtools/sort/tests/nextflow.config @@ -1,7 +1,6 @@ process { withName: SAMTOOLS_SORT { - ext.prefix = { "${meta.id}.sorted" } + ext.prefix = { "${meta.id}.sorted" } } - } diff --git a/modules/nf-core/samtools/sort/tests/nextflow_cram.config b/modules/nf-core/samtools/sort/tests/nextflow_cram.config index 3a8c0188..8ebc9d91 100644 --- a/modules/nf-core/samtools/sort/tests/nextflow_cram.config +++ b/modules/nf-core/samtools/sort/tests/nextflow_cram.config @@ -1,8 +1,7 @@ process { withName: SAMTOOLS_SORT { - ext.prefix = { "${meta.id}.sorted" } - ext.args = "--write-index --output-fmt cram" + ext.prefix = { "${meta.id}.sorted" } + ext.args = "--write-index --output-fmt cram" } - } diff --git a/modules/nf-core/samtools/sort/tests/nextflow_sam.config b/modules/nf-core/samtools/sort/tests/nextflow_sam.config new file mode 100644 index 00000000..29ee6a88 --- /dev/null +++ b/modules/nf-core/samtools/sort/tests/nextflow_sam.config @@ -0,0 +1,7 @@ +process { + + withName: SAMTOOLS_SORT { + ext.prefix = { "${meta.id}.sorted" } + ext.args = "--output-fmt sam" + } +} diff --git a/modules/nf-core/samtools/stats/environment.yml b/modules/nf-core/samtools/stats/environment.yml index 89e12a64..946bb362 100644 --- a/modules/nf-core/samtools/stats/environment.yml +++ b/modules/nf-core/samtools/stats/environment.yml @@ -5,6 +5,6 @@ channels: - bioconda dependencies: # renovate: datasource=conda depName=bioconda/htslib - - bioconda::htslib=1.22.1 + - bioconda::htslib=1.23.1 # renovate: datasource=conda depName=bioconda/samtools - - bioconda::samtools=1.22.1 + - bioconda::samtools=1.23.1 diff --git a/modules/nf-core/samtools/stats/main.nf b/modules/nf-core/samtools/stats/main.nf index 57d24680..28457e68 100644 --- a/modules/nf-core/samtools/stats/main.nf +++ b/modules/nf-core/samtools/stats/main.nf @@ -1,15 +1,15 @@ process SAMTOOLS_STATS { - 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/samtools:1.22.1--h96c455f_0' : - 'biocontainers/samtools:1.22.1--h96c455f_0' }" + container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/8c/8c5d2818c8b9f58e1fba77ce219fdaf32087ae53e857c4a496402978af26e78c/data' + : 'community.wave.seqera.io/library/htslib_samtools:1.23.1--5b6bb4ede7e612e5'}" input: tuple val(meta), path(input), path(input_index) - tuple val(meta2), path(fasta) + tuple val(meta2), path(fasta), path(fai) output: tuple val(meta), path("*.stats"), emit: stats @@ -19,8 +19,8 @@ process SAMTOOLS_STATS { task.ext.when == null || task.ext.when script: - 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 reference = fasta ? "--reference ${fasta}" : "" """ samtools \\ diff --git a/modules/nf-core/samtools/stats/meta.yml b/modules/nf-core/samtools/stats/meta.yml index 5c59cce4..5fd7e76d 100644 --- a/modules/nf-core/samtools/stats/meta.yml +++ b/modules/nf-core/samtools/stats/meta.yml @@ -41,7 +41,12 @@ input: - fasta: type: file description: Reference file the CRAM was created with (optional) - pattern: "*.{fasta,fa}" + pattern: "*.{fasta,fa,fna}" + ontologies: [] + - fai: + type: file + description: FASTA ref index file + pattern: "*.{fasta,fa,fna}.fai" ontologies: [] output: stats: @@ -86,3 +91,4 @@ maintainers: - "@drpatelh" - "@FriederikeHanssen" - "@ramprasadn" + - "@matthdsm" diff --git a/modules/nf-core/samtools/stats/tests/main.nf.test b/modules/nf-core/samtools/stats/tests/main.nf.test index 5bc89309..140adf34 100644 --- a/modules/nf-core/samtools/stats/tests/main.nf.test +++ b/modules/nf-core/samtools/stats/tests/main.nf.test @@ -19,7 +19,7 @@ nextflow_process { 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] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -44,7 +44,8 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true) ]) """ } @@ -70,7 +71,7 @@ nextflow_process { 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] = [[],[]] + input[1] = [[],[],[]] """ } } @@ -97,7 +98,8 @@ nextflow_process { ]) input[1] = Channel.of([ [ id:'genome' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta.fai', checkIfExists: true) ]) """ } diff --git a/modules/nf-core/samtools/stats/tests/main.nf.test.snap b/modules/nf-core/samtools/stats/tests/main.nf.test.snap index 94d981b2..975d44a1 100644 --- a/modules/nf-core/samtools/stats/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/stats/tests/main.nf.test.snap @@ -8,14 +8,14 @@ "id": "test", "single_end": false }, - "test.stats:md5,f4aec6c41b73d34ac2fc6b3253aa39ba" + "test.stats:md5,e4d6cf0e75cebd0bafa84141e0b6929b" ] ], "1": [ [ "SAMTOOLS_STATS", "samtools", - "1.22.1" + "1.23.1" ] ], "stats": [ @@ -24,23 +24,23 @@ "id": "test", "single_end": false }, - "test.stats:md5,f4aec6c41b73d34ac2fc6b3253aa39ba" + "test.stats:md5,e4d6cf0e75cebd0bafa84141e0b6929b" ] ], "versions_samtools": [ [ "SAMTOOLS_STATS", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-11-01T02:27:18.460724" + "timestamp": "2026-03-19T09:05:39.987454" }, "bam - stub": { "content": [ @@ -58,7 +58,7 @@ [ "SAMTOOLS_STATS", "samtools", - "1.22.1" + "1.23.1" ] ], "stats": [ @@ -74,16 +74,16 @@ [ "SAMTOOLS_STATS", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-11-01T02:27:30.245839" + "timestamp": "2026-03-19T09:05:47.495502" }, "cram - stub": { "content": [ @@ -101,7 +101,7 @@ [ "SAMTOOLS_STATS", "samtools", - "1.22.1" + "1.23.1" ] ], "stats": [ @@ -117,16 +117,16 @@ [ "SAMTOOLS_STATS", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-11-01T02:27:39.041649" + "timestamp": "2026-03-19T09:05:56.38373" }, "bam": { "content": [ @@ -137,14 +137,14 @@ "id": "test", "single_end": false }, - "test.stats:md5,41ba8ad30ddb598dadb177a54c222ab9" + "test.stats:md5,80f94eb0b68e213bdc8231109d3b43ad" ] ], "1": [ [ "SAMTOOLS_STATS", "samtools", - "1.22.1" + "1.23.1" ] ], "stats": [ @@ -153,22 +153,22 @@ "id": "test", "single_end": false }, - "test.stats:md5,41ba8ad30ddb598dadb177a54c222ab9" + "test.stats:md5,80f94eb0b68e213bdc8231109d3b43ad" ] ], "versions_samtools": [ [ "SAMTOOLS_STATS", "samtools", - "1.22.1" + "1.23.1" ] ] } ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.0" + "nextflow": "25.10.4" }, - "timestamp": "2025-11-01T02:26:55.988241" + "timestamp": "2026-03-19T09:05:24.59441" } } \ No newline at end of file diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 6fe7d5fe..4b31e4d6 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "InProgress", "datePublished": "2026-04-30T13:33:09+00:00", - "description": "

\n \n \n \"nf-core/chipseq\"\n \n

\n\n[![Open in GitHub Codespaces](https://img.shields.io/badge/Open_In_GitHub_Codespaces-black?labelColor=grey&logo=github)](https://github.com/codespaces/new/nf-core/chipseq)\n[![GitHub Actions CI Status](https://github.com/nf-core/chipseq/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/chipseq/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/chipseq/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/chipseq/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/chipseq/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.3240506-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.3240506)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.10.4-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-4.0.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/4.0.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/chipseq)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23chipseq-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/chipseq)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nfcore/chipseq** is a bioinformatics analysis pipeline used for Chromatin ImmunoPrecipitation sequencing (ChIP-seq) data.\n\nOn release, automated continuous integration tests run the pipeline on a [full-sized dataset](https://github.com/nf-core/test-datasets/tree/chipseq#full-test-dataset-origin) on the AWS cloud infrastructure. The dataset consists of FoxA1 (transcription factor) and EZH2 (histone,mark) IP experiments from _Franco et al. 2015_ ([GEO: GSE59530](https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE59530), [PMID: 25752574](https://pubmed.ncbi.nlm.nih.gov/25752574/)) and _Popovic et al. 2014_ ([GEO: GSE57632](https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE57632), [PMID: 25188243](https://pubmed.ncbi.nlm.nih.gov/25188243/)), respectively. This ensures that the pipeline runs on AWS, has sensible resource allocation defaults set to run on real-world datasets, and permits the persistent storage of results to benchmark between pipeline releases and other analysis sources. The results obtained from running the full-sized tests can be viewed on the [nf-core website](https://nf-co.re/chipseq/results).\n\nThe pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It uses Docker/Singularity containers making installation trivial and results highly reproducible. The [Nextflow DSL2](https://www.nextflow.io/docs/latest/dsl2.html) implementation of this pipeline uses one container per process which makes it much easier to maintain and update software dependencies. Where possible, these processes have been submitted to and installed from [nf-core/modules](https://github.com/nf-core/modules) in order to make them available to all nf-core pipelines, and to everyone within the Nextflow community!\n\n## Online videos\n\nA short talk about the history, current status and functionality on offer in this pipeline was given by Jose Espinosa-Carrasco ([@joseespinosa](https://github.com/joseespinosa)) on [26th July 2022](https://nf-co.re/events/2022/bytesize-chipseq) as part of the nf-core/bytesize series.\n\nYou can find numerous talks on the [nf-core events page](https://nf-co.re/events) from various topics including writing pipelines/modules in Nextflow DSL2, using nf-core tooling, running nf-core pipelines as well as more generic content like contributing to Github. Please check them out!\n\n## Pipeline summary\n\n![nf-core/chipseq metro map](docs/images/nf-core-chipseq_metro_map_grey.png)\n\n1. Raw read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/))\n2. Adapter trimming ([`Trim Galore!`](https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/))\n3. Choice of multiple aligners\n 1.([`BWA`](https://sourceforge.net/projects/bio-bwa/files/))\n 2.([`Chromap`](https://github.com/haowenz/chromap))\n 3.([`Bowtie2`](http://bowtie-bio.sourceforge.net/bowtie2/index.shtml))\n 4.([`STAR`](https://github.com/alexdobin/STAR))\n4. Mark duplicates ([`picard`](https://broadinstitute.github.io/picard/))\n5. Merge alignments from multiple libraries of the same sample ([`picard`](https://broadinstitute.github.io/picard/))\n 1. Re-mark duplicates ([`picard`](https://broadinstitute.github.io/picard/))\n 2. Filtering to remove:\n - reads mapping to blacklisted regions ([`SAMtools`](https://sourceforge.net/projects/samtools/files/samtools/), [`BEDTools`](https://github.com/arq5x/bedtools2/))\n - reads that are marked as duplicates ([`SAMtools`](https://sourceforge.net/projects/samtools/files/samtools/))\n - reads that are not marked as primary alignments ([`SAMtools`](https://sourceforge.net/projects/samtools/files/samtools/))\n - reads that are unmapped ([`SAMtools`](https://sourceforge.net/projects/samtools/files/samtools/))\n - reads that map to multiple locations ([`SAMtools`](https://sourceforge.net/projects/samtools/files/samtools/))\n - reads containing > 4 mismatches ([`BAMTools`](https://github.com/pezmaster31/bamtools))\n - reads that have an insert size > 2kb ([`BAMTools`](https://github.com/pezmaster31/bamtools); _paired-end only_)\n - reads that map to different chromosomes ([`Pysam`](http://pysam.readthedocs.io/en/latest/installation.html); _paired-end only_)\n - reads that arent in FR orientation ([`Pysam`](http://pysam.readthedocs.io/en/latest/installation.html); _paired-end only_)\n - reads where only one read of the pair fails the above criteria ([`Pysam`](http://pysam.readthedocs.io/en/latest/installation.html); _paired-end only_)\n 3. Alignment-level QC and estimation of library complexity ([`picard`](https://broadinstitute.github.io/picard/), [`Preseq`](http://smithlabresearch.org/software/preseq/))\n 4. Create normalised bigWig files scaled to 1 million mapped reads ([`BEDTools`](https://github.com/arq5x/bedtools2/), [`bedGraphToBigWig`](http://hgdownload.soe.ucsc.edu/admin/exe/))\n 5. Generate gene-body meta-profile from bigWig files ([`deepTools`](https://deeptools.readthedocs.io/en/develop/content/tools/plotProfile.html))\n 6. Calculate genome-wide IP enrichment relative to control ([`deepTools`](https://deeptools.readthedocs.io/en/develop/content/tools/plotFingerprint.html))\n 7. Calculate strand cross-correlation peak and ChIP-seq quality measures including NSC and RSC ([`phantompeakqualtools`](https://github.com/kundajelab/phantompeakqualtools))\n 8. Call broad/narrow peaks ([`MACS3`](https://github.com/macs3-project/MACS))\n 9. Annotate peaks relative to gene features ([`HOMER`](http://homer.ucsd.edu/homer/download.html))\n 10. Create consensus peakset across all samples and create tabular file to aid in the filtering of the data ([`BEDTools`](https://github.com/arq5x/bedtools2/))\n 11. Count reads in consensus peaks ([`featureCounts`](http://bioinf.wehi.edu.au/featureCounts/))\n 12. PCA and clustering ([`R`](https://www.r-project.org/), [`DESeq2`](https://bioconductor.org/packages/release/bioc/html/DESeq2.html))\n6. Create IGV session file containing bigWig tracks, peaks and differential sites for data visualisation ([`IGV`](https://software.broadinstitute.org/software/igv/)).\n7. Present QC for raw read, alignment, peak-calling and differential binding results ([`MultiQC`](http://multiqc.info/), [`R`](https://www.r-project.org/))\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/get_started/environment_setup/overview) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/get_started/run-your-first-pipeline) with `-profile test` before running the workflow on actual data.\n\nTo run on your data, prepare a tab-separated samplesheet with your input data. Please follow the [documentation on samplesheets](https://nf-co.re/chipseq/usage#samplesheet-input) for more details. An example samplesheet for running the pipeline looks as follows:\n\n```csv title=\"samplesheet.csv\"\nsample,fastq_1,fastq_2,replicate,antibody,control,control_replicate\nWT_BCATENIN_IP,BLA203A1_S27_L006_R1_001.fastq.gz,,1,BCATENIN,WT_INPUT,1\nWT_BCATENIN_IP,BLA203A25_S16_L001_R1_001.fastq.gz,,2,BCATENIN,WT_INPUT,2\nWT_BCATENIN_IP,BLA203A25_S16_L002_R1_001.fastq.gz,,2,BCATENIN,WT_INPUT,2\nWT_BCATENIN_IP,BLA203A25_S16_L003_R1_001.fastq.gz,,2,BCATENIN,WT_INPUT,2\nWT_BCATENIN_IP,BLA203A49_S40_L001_R1_001.fastq.gz,,3,BCATENIN,WT_INPUT,3\nWT_INPUT,BLA203A6_S32_L006_R1_001.fastq.gz,,1,,,\nWT_INPUT,BLA203A30_S21_L001_R1_001.fastq.gz,,2,,,\nWT_INPUT,BLA203A30_S21_L002_R1_001.fastq.gz,,2,,,\nWT_INPUT,BLA203A31_S21_L003_R1_001.fastq.gz,,3,,,\n```\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/chipseq --input samplesheet.csv --outdir --genome GRCh37 -profile \n```\n\nSee [usage docs](https://nf-co.re/chipseq/usage) for all of the available options when running the pipeline.\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/running/run-pipelines#using-parameter-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/chipseq/usage) and the [parameter documentation](https://nf-co.re/chipseq/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/chipseq/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/chipseq/output).\n\n## Credits\n\nThese scripts were originally written by Chuan Wang ([@chuan-wang](https://github.com/chuan-wang)) and Phil Ewels ([@ewels](https://github.com/ewels)) for use at the [National Genomics Infrastructure](https://portal.scilifelab.se/genomics/) at [SciLifeLab](http://www.scilifelab.se/) in Stockholm, Sweden. The pipeline was re-implemented by Harshil Patel ([@drpatelh](https://github.com/drpatelh)) from [Seqera Labs, Spain](https://seqera.io/) and converted to Nextflow DSL2 by Jose Espinosa-Carrasco ([@JoseEspinosa](https://github.com/JoseEspinosa)) from [The Comparative Bioinformatics Group](https://www.crg.eu/en/cedric_notredame) at [The Centre for Genomic Regulation, Spain](https://www.crg.eu/).\n\nThe pipeline workflow diagram was designed by Sarah Guinchard ([@G-Sarah](https://github.com/G-Sarah)).\n\nMany thanks to others who have helped out and contributed along the way too, including (but not limited to):\n[@apeltzer](https://github.com/apeltzer), [@bc2zb](https://github.com/bc2zb), [@bjlang](https://github.com/bjlang),\n[@crickbabs](https://github.com/crickbabs), [@drejom](https://github.com/drejom),\n[@houghtos](https://github.com/houghtos), [@KevinMenden](https://github.com/KevinMenden),\n[@mashehu](https://github.com/mashehu), [@pditommaso](https://github.com/pditommaso),\n[@Rotholandus](https://github.com/Rotholandus), [@sofiahaglund](https://github.com/sofiahaglund),\n[@tiagochst](https://github.com/tiagochst), [@winni2k](https://github.com/winni2k) and [@Kevin-Brockers](https://github.com/Kevin-Brockers).\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](docs/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#chipseq` channel](https://nfcore.slack.com/channels/chipseq) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\nIf you use nf-core/chipseq for your analysis, please cite it using the following doi: [10.5281/zenodo.3240506](https://doi.org/10.5281/zenodo.3240506)\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

\n \n \n \"nf-core/chipseq\"\n \n

\n\n[![Open in GitHub Codespaces](https://img.shields.io/badge/Open_In_GitHub_Codespaces-black?labelColor=grey&logo=github)](https://github.com/codespaces/new/nf-core/chipseq)\n[![GitHub Actions CI Status](https://github.com/nf-core/chipseq/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/chipseq/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/chipseq/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/chipseq/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/chipseq/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.3240506-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.3240506)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/version-%E2%89%A525.10.4-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-4.0.2-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/4.0.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/chipseq)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23chipseq-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/chipseq)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nfcore/chipseq** is a bioinformatics analysis pipeline used for Chromatin ImmunoPrecipitation sequencing (ChIP-seq) data.\n\nOn release, automated continuous integration tests run the pipeline on a [full-sized dataset](https://github.com/nf-core/test-datasets/tree/chipseq#full-test-dataset-origin) on the AWS cloud infrastructure. The dataset consists of FoxA1 (transcription factor) and EZH2 (histone,mark) IP experiments from _Franco et al. 2015_ ([GEO: GSE59530](https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE59530), [PMID: 25752574](https://pubmed.ncbi.nlm.nih.gov/25752574/)) and _Popovic et al. 2014_ ([GEO: GSE57632](https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE57632), [PMID: 25188243](https://pubmed.ncbi.nlm.nih.gov/25188243/)), respectively. This ensures that the pipeline runs on AWS, has sensible resource allocation defaults set to run on real-world datasets, and permits the persistent storage of results to benchmark between pipeline releases and other analysis sources. The results obtained from running the full-sized tests can be viewed on the [nf-core website](https://nf-co.re/chipseq/results).\n\nThe pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It uses Docker/Singularity containers making installation trivial and results highly reproducible. The [Nextflow DSL2](https://www.nextflow.io/docs/latest/dsl2.html) implementation of this pipeline uses one container per process which makes it much easier to maintain and update software dependencies. Where possible, these processes have been submitted to and installed from [nf-core/modules](https://github.com/nf-core/modules) in order to make them available to all nf-core pipelines, and to everyone within the Nextflow community!\n\n## Online videos\n\nA short talk about the history, current status and functionality on offer in this pipeline was given by Jose Espinosa-Carrasco ([@joseespinosa](https://github.com/joseespinosa)) on [26th July 2022](https://nf-co.re/events/2022/bytesize-chipseq) as part of the nf-core/bytesize series.\n\nYou can find numerous talks on the [nf-core events page](https://nf-co.re/events) from various topics including writing pipelines/modules in Nextflow DSL2, using nf-core tooling, running nf-core pipelines as well as more generic content like contributing to Github. Please check them out!\n\n## Pipeline summary\n\n![nf-core/chipseq metro map](docs/images/nf-core-chipseq_metro_map_grey.png)\n\n1. Raw read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/))\n2. Adapter trimming ([`Trim Galore!`](https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/))\n3. Choice of multiple aligners\n 1.([`BWA`](https://sourceforge.net/projects/bio-bwa/files/))\n 2.([`Chromap`](https://github.com/haowenz/chromap))\n 3.([`Bowtie2`](http://bowtie-bio.sourceforge.net/bowtie2/index.shtml))\n 4.([`STAR`](https://github.com/alexdobin/STAR))\n4. Mark duplicates ([`picard`](https://broadinstitute.github.io/picard/))\n5. Merge alignments from multiple libraries of the same sample ([`picard`](https://broadinstitute.github.io/picard/))\n 1. Re-mark duplicates ([`picard`](https://broadinstitute.github.io/picard/))\n 2. Filtering to remove:\n - reads mapping to blacklisted regions ([`SAMtools`](https://sourceforge.net/projects/samtools/files/samtools/), [`BEDTools`](https://github.com/arq5x/bedtools2/))\n - reads that are marked as duplicates ([`SAMtools`](https://sourceforge.net/projects/samtools/files/samtools/))\n - reads that are not marked as primary alignments ([`SAMtools`](https://sourceforge.net/projects/samtools/files/samtools/))\n - reads that are unmapped ([`SAMtools`](https://sourceforge.net/projects/samtools/files/samtools/))\n - reads that map to multiple locations ([`SAMtools`](https://sourceforge.net/projects/samtools/files/samtools/))\n - reads containing > 4 mismatches ([`BAMTools`](https://github.com/pezmaster31/bamtools))\n - reads that have an insert size > 2kb ([`BAMTools`](https://github.com/pezmaster31/bamtools); _paired-end only_)\n - reads that map to different chromosomes ([`Pysam`](http://pysam.readthedocs.io/en/latest/installation.html); _paired-end only_)\n - reads that arent in FR orientation ([`Pysam`](http://pysam.readthedocs.io/en/latest/installation.html); _paired-end only_)\n - reads where only one read of the pair fails the above criteria ([`Pysam`](http://pysam.readthedocs.io/en/latest/installation.html); _paired-end only_)\n 3. Alignment-level QC and estimation of library complexity:\n - [`picard`](https://broadinstitute.github.io/picard/)\n - [`Preseq`](http://smithlabresearch.org/software/preseq/) (skipped by default)\n 4. Create normalised bigWig files scaled to 1 million mapped reads ([`BEDTools`](https://github.com/arq5x/bedtools2/), [`bedGraphToBigWig`](http://hgdownload.soe.ucsc.edu/admin/exe/))\n 5. Generate gene-body meta-profile from bigWig files ([`deepTools`](https://deeptools.readthedocs.io/en/develop/content/tools/plotProfile.html))\n 6. Calculate genome-wide IP enrichment relative to control ([`deepTools`](https://deeptools.readthedocs.io/en/develop/content/tools/plotFingerprint.html))\n 7. Calculate strand cross-correlation peak and ChIP-seq quality measures including NSC and RSC ([`phantompeakqualtools`](https://github.com/kundajelab/phantompeakqualtools))\n 8. Call broad/narrow peaks ([`MACS3`](https://github.com/macs3-project/MACS))\n 9. Annotate peaks relative to gene features ([`HOMER`](http://homer.ucsd.edu/homer/download.html))\n 10. Create consensus peakset across all samples and create tabular file to aid in the filtering of the data ([`BEDTools`](https://github.com/arq5x/bedtools2/))\n 11. Count reads in consensus peaks ([`featureCounts`](https://subread.sourceforge.net/featureCounts.html))\n 12. PCA and clustering ([`R`](https://www.r-project.org/), [`DESeq2`](https://bioconductor.org/packages/release/bioc/html/DESeq2.html))\n6. Create IGV session file containing bigWig tracks, peaks and differential sites for data visualisation ([`IGV`](https://software.broadinstitute.org/software/igv/)).\n7. Present QC for raw read, alignment, peak-calling and differential binding results ([`MultiQC`](http://multiqc.info/), [`R`](https://www.r-project.org/))\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/get_started/environment_setup/overview) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/get_started/run-your-first-pipeline) with `-profile test` before running the workflow on actual data.\n\nTo run on your data, prepare a tab-separated samplesheet with your input data. Please follow the [documentation on samplesheets](https://nf-co.re/chipseq/usage#samplesheet-input) for more details. An example samplesheet for running the pipeline looks as follows:\n\n```csv title=\"samplesheet.csv\"\nsample,fastq_1,fastq_2,replicate,antibody,control,control_replicate\nWT_BCATENIN_IP,BLA203A1_S27_L006_R1_001.fastq.gz,,1,BCATENIN,WT_INPUT,1\nWT_BCATENIN_IP,BLA203A25_S16_L001_R1_001.fastq.gz,,2,BCATENIN,WT_INPUT,2\nWT_BCATENIN_IP,BLA203A25_S16_L002_R1_001.fastq.gz,,2,BCATENIN,WT_INPUT,2\nWT_BCATENIN_IP,BLA203A25_S16_L003_R1_001.fastq.gz,,2,BCATENIN,WT_INPUT,2\nWT_BCATENIN_IP,BLA203A49_S40_L001_R1_001.fastq.gz,,3,BCATENIN,WT_INPUT,3\nWT_INPUT,BLA203A6_S32_L006_R1_001.fastq.gz,,1,,,\nWT_INPUT,BLA203A30_S21_L001_R1_001.fastq.gz,,2,,,\nWT_INPUT,BLA203A30_S21_L002_R1_001.fastq.gz,,2,,,\nWT_INPUT,BLA203A31_S21_L003_R1_001.fastq.gz,,3,,,\n```\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/chipseq --input samplesheet.csv --outdir --genome GRCh37 -profile \n```\n\nSee [usage docs](https://nf-co.re/chipseq/usage) for all of the available options when running the pipeline.\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/running/run-pipelines#using-parameter-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/chipseq/usage) and the [parameter documentation](https://nf-co.re/chipseq/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/chipseq/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/chipseq/output).\n\n## Credits\n\nThese scripts were originally written by Chuan Wang ([@chuan-wang](https://github.com/chuan-wang)) and Phil Ewels ([@ewels](https://github.com/ewels)) for use at the [National Genomics Infrastructure](https://portal.scilifelab.se/genomics/) at [SciLifeLab](http://www.scilifelab.se/) in Stockholm, Sweden. The pipeline was re-implemented by Harshil Patel ([@drpatelh](https://github.com/drpatelh)) from [Seqera Labs, Spain](https://seqera.io/) and converted to Nextflow DSL2 by Jose Espinosa-Carrasco ([@JoseEspinosa](https://github.com/JoseEspinosa)) from [The Comparative Bioinformatics Group](https://www.crg.eu/en/cedric_notredame) at [The Centre for Genomic Regulation, Spain](https://www.crg.eu/).\n\nThe pipeline workflow diagram was designed by Sarah Guinchard ([@G-Sarah](https://github.com/G-Sarah)).\n\nMany thanks to others who have helped out and contributed along the way too, including (but not limited to):\n[@apeltzer](https://github.com/apeltzer), [@bc2zb](https://github.com/bc2zb), [@bjlang](https://github.com/bjlang),\n[@crickbabs](https://github.com/crickbabs), [@drejom](https://github.com/drejom),\n[@houghtos](https://github.com/houghtos), [@KevinMenden](https://github.com/KevinMenden),\n[@mashehu](https://github.com/mashehu), [@pditommaso](https://github.com/pditommaso),\n[@Rotholandus](https://github.com/Rotholandus), [@sofiahaglund](https://github.com/sofiahaglund),\n[@tiagochst](https://github.com/tiagochst), [@winni2k](https://github.com/winni2k) and [@Kevin-Brockers](https://github.com/Kevin-Brockers).\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](docs/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#chipseq` channel](https://nfcore.slack.com/channels/chipseq) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\nIf you use nf-core/chipseq for your analysis, please cite it using the following doi: [10.5281/zenodo.3240506](https://doi.org/10.5281/zenodo.3240506)\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" diff --git a/subworkflows/local/align_star/main.nf b/subworkflows/local/align_star/main.nf index 600c6d5a..d2a811d5 100644 --- a/subworkflows/local/align_star/main.nf +++ b/subworkflows/local/align_star/main.nf @@ -36,7 +36,7 @@ workflow ALIGN_STAR { tab = STAR_ALIGN.out.tab // channel: [ val(meta), tab ] bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), [ bam ] ] - bai = BAM_SORT_STATS_SAMTOOLS.out.bai // channel: [ val(meta), [ bai ] ] + bai = BAM_SORT_STATS_SAMTOOLS.out.index // channel: [ val(meta), [ bai ] ] stats = BAM_SORT_STATS_SAMTOOLS.out.stats // channel: [ val(meta), [ stats ] ] flagstat = BAM_SORT_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), [ flagstat ] ] idxstats = BAM_SORT_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), [ idxstats ] ] diff --git a/subworkflows/local/bam_filter_bamtools/main.nf b/subworkflows/local/bam_filter_bamtools/main.nf index 65bea3ed..3c61b350 100644 --- a/subworkflows/local/bam_filter_bamtools/main.nf +++ b/subworkflows/local/bam_filter_bamtools/main.nf @@ -10,7 +10,7 @@ workflow BAM_FILTER_BAMTOOLS { take: ch_bam_bai // channel: [ val(meta), [ bam ], [bai] ] ch_bed // channel: [ bed ] - ch_fasta // channel: [ fasta ] + ch_fasta // channel: [ val(meta), fasta ] ch_bamtools_filter_se_config // channel: [ config_file ] ch_bamtools_filter_pe_config // channel: [ config_file ] @@ -27,39 +27,35 @@ workflow BAM_FILTER_BAMTOOLS { ch_bamtools_filter_pe_config ) - BAMTOOLS_FILTER - .out - .bam - .branch { - meta, bam -> - single_end: meta.single_end - return [ meta, bam ] - paired_end: !meta.single_end - return [ meta, bam ] - } - .set { ch_bam } + ch_bam_single_end = BAMTOOLS_FILTER.out.bam + .filter { meta, _bam -> meta.single_end == true } + .map { meta, bam -> [meta, bam] } + + ch_bam_paired_end = BAMTOOLS_FILTER.out.bam + .filter { meta, _bam -> meta.single_end != true } + .map { meta, bam -> [meta, bam] } // // Index SE BAM file // - SAMTOOLS_INDEX { - ch_bam.single_end - } + SAMTOOLS_INDEX ( + ch_bam_single_end + ) // // Run samtools stats, flagstat and idxstats on SE BAM // BAM_STATS_SAMTOOLS ( - ch_bam.single_end.join(SAMTOOLS_INDEX.out.bai), - ch_fasta + ch_bam_single_end.join(SAMTOOLS_INDEX.out.index), + ch_fasta.map { meta, fasta -> [ meta, fasta, [] ] } ) // // Name sort PE BAM before filtering with pysam // SAMTOOLS_SORT ( - ch_bam.paired_end, - ch_fasta, + ch_bam_paired_end, + ch_fasta.map { meta, fasta -> [ meta, fasta, [] ] }, '' ) @@ -75,14 +71,14 @@ workflow BAM_FILTER_BAMTOOLS { // BAM_SORT_STATS_SAMTOOLS ( BAM_REMOVE_ORPHANS.out.bam, - ch_fasta + ch_fasta.map { meta, fasta -> [ meta, fasta, [] ] } ) emit: - name_bam = SAMTOOLS_SORT.out.bam // channel: [ val(meta), [ bam ] ] - bam = BAM_SORT_STATS_SAMTOOLS.out.bam.mix(ch_bam.single_end) // channel: [ val(meta), [ bam ] ] - bai = BAM_SORT_STATS_SAMTOOLS.out.bai.mix(SAMTOOLS_INDEX.out.bai) // channel: [ val(meta), [ bai ] ] - stats = BAM_SORT_STATS_SAMTOOLS.out.stats.mix(BAM_STATS_SAMTOOLS.out.stats) // channel: [ val(meta), [ stats ] ] - flagstat = BAM_SORT_STATS_SAMTOOLS.out.flagstat.mix(BAM_STATS_SAMTOOLS.out.flagstat) // channel: [ val(meta), [ flagstat ] ] - idxstats = BAM_SORT_STATS_SAMTOOLS.out.idxstats.mix(BAM_STATS_SAMTOOLS.out.idxstats) // channel: [ val(meta), [ idxstats ] ] + name_bam = SAMTOOLS_SORT.out.bam // channel: [ val(meta), [ bam ] ] + bam = BAM_SORT_STATS_SAMTOOLS.out.bam.mix(ch_bam_single_end) // channel: [ val(meta), [ bam ] ] + bai = BAM_SORT_STATS_SAMTOOLS.out.index.mix(SAMTOOLS_INDEX.out.index) // channel: [ val(meta), [ bai ] ] + stats = BAM_SORT_STATS_SAMTOOLS.out.stats.mix(BAM_STATS_SAMTOOLS.out.stats) // channel: [ val(meta), [ stats ] ] + flagstat = BAM_SORT_STATS_SAMTOOLS.out.flagstat.mix(BAM_STATS_SAMTOOLS.out.flagstat) // channel: [ val(meta), [ flagstat ] ] + idxstats = BAM_SORT_STATS_SAMTOOLS.out.idxstats.mix(BAM_STATS_SAMTOOLS.out.idxstats) // channel: [ val(meta), [ idxstats ] ] } diff --git a/subworkflows/nf-core/bam_markduplicates_picard/main.nf b/subworkflows/nf-core/bam_markduplicates_picard/main.nf index c33064eb..03d7e575 100644 --- a/subworkflows/nf-core/bam_markduplicates_picard/main.nf +++ b/subworkflows/nf-core/bam_markduplicates_picard/main.nf @@ -7,40 +7,34 @@ include { SAMTOOLS_INDEX } from '../../../modules/nf-core/samtools/index/ include { BAM_STATS_SAMTOOLS } from '../bam_stats_samtools/main' workflow BAM_MARKDUPLICATES_PICARD { - take: - ch_reads // channel: [ val(meta), path(reads) ] - ch_fasta // channel: [ val(meta), path(fasta) ] - ch_fai // channel: [ val(meta), path(fai) ] + ch_reads // channel: [ val(meta), path(reads) ] + ch_fasta_fai // channel: [ val(meta), path(fasta), path(fai)] main: - PICARD_MARKDUPLICATES ( ch_reads, ch_fasta, ch_fai ) + PICARD_MARKDUPLICATES(ch_reads, ch_fasta_fai) ch_markdup = PICARD_MARKDUPLICATES.out.bam.mix(PICARD_MARKDUPLICATES.out.cram) - SAMTOOLS_INDEX ( ch_markdup ) + SAMTOOLS_INDEX(ch_markdup) + + ch_reads_index = ch_markdup.join(SAMTOOLS_INDEX.out.index, by: [0]) - ch_reads_index = ch_markdup - .join(SAMTOOLS_INDEX.out.bai, by: [0], remainder: true) - .join(SAMTOOLS_INDEX.out.crai, by: [0], remainder: true) - .join(SAMTOOLS_INDEX.out.csi, by: [0], remainder: true) - .map{meta, reads, bai, crai, csi -> - if (bai) [ meta, reads, bai ] - else if (crai) [ meta, reads, crai ] - else [ meta, reads, csi ] - } + BAM_STATS_SAMTOOLS(ch_reads_index, ch_fasta_fai) - BAM_STATS_SAMTOOLS ( ch_reads_index, ch_fasta ) + ch_per_sample_mqc_bundle = BAM_STATS_SAMTOOLS.out.stats + .join(BAM_STATS_SAMTOOLS.out.flagstat, remainder: true) + .join(BAM_STATS_SAMTOOLS.out.idxstats, remainder: true) + .join(PICARD_MARKDUPLICATES.out.metrics, remainder: true) + .map { row -> [row[0], row.drop(1).findAll { f -> f != null }.collectMany { e -> (e instanceof List) ? e : [e] }] } emit: - bam = PICARD_MARKDUPLICATES.out.bam // channel: [ val(meta), path(bam) ] - cram = PICARD_MARKDUPLICATES.out.cram // channel: [ val(meta), path(cram) ] - metrics = PICARD_MARKDUPLICATES.out.metrics // channel: [ val(meta), path(metrics) ] - bai = SAMTOOLS_INDEX.out.bai // channel: [ val(meta), path(bai) ] - crai = SAMTOOLS_INDEX.out.crai // channel: [ val(meta), path(crai) ] - csi = SAMTOOLS_INDEX.out.csi // channel: [ val(meta), path(csi) ] - - stats = BAM_STATS_SAMTOOLS.out.stats // channel: [ val(meta), path(stats) ] - flagstat = BAM_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), path(flagstat) ] - idxstats = BAM_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), path(idxstats) ] + bam = PICARD_MARKDUPLICATES.out.bam // channel: [ val(meta), path(bam) ] + cram = PICARD_MARKDUPLICATES.out.cram // channel: [ val(meta), path(cram) ] + metrics = PICARD_MARKDUPLICATES.out.metrics // channel: [ val(meta), path(metrics) ] + index = SAMTOOLS_INDEX.out.index // channel: [ val(meta), path(index) ] + stats = BAM_STATS_SAMTOOLS.out.stats // channel: [ val(meta), path(stats) ] + flagstat = BAM_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), path(flagstat) ] + idxstats = BAM_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), path(idxstats) ] + per_sample_mqc_bundle = ch_per_sample_mqc_bundle // channel: [ val(meta), list(files) ] } diff --git a/subworkflows/nf-core/bam_markduplicates_picard/meta.yml b/subworkflows/nf-core/bam_markduplicates_picard/meta.yml index 433d35b2..170071e0 100644 --- a/subworkflows/nf-core/bam_markduplicates_picard/meta.yml +++ b/subworkflows/nf-core/bam_markduplicates_picard/meta.yml @@ -18,14 +18,10 @@ input: description: | Sequence reads in BAM/CRAM/SAM format Structure: [ val(meta), path(reads) ] - - ch_fasta: + - ch_fasta_fai: description: | Reference genome fasta file required for CRAM input - Structure: [ path(fasta) ] - - ch_fasta: - description: | - Index of the reference genome fasta file - Structure: [ path(fai) ] + Structure: [ path(fasta), path(fai) ] output: - bam: description: | @@ -59,6 +55,10 @@ output: description: | File containing samtools idxstats output Structure: [ val(meta), path(idxstats) ] + - per_sample_mqc_bundle: + description: | + Per-sample MultiQC-feeding outputs (stats, flagstat, idxstats, metrics) joined on meta. + Structure: [ val(meta), list(files) ] - versions: description: | Files containing software versions diff --git a/subworkflows/nf-core/bam_markduplicates_picard/tests/main.nf.test b/subworkflows/nf-core/bam_markduplicates_picard/tests/main.nf.test index 816ff3ef..72510d02 100644 --- a/subworkflows/nf-core/bam_markduplicates_picard/tests/main.nf.test +++ b/subworkflows/nf-core/bam_markduplicates_picard/tests/main.nf.test @@ -30,10 +30,7 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) """ @@ -44,9 +41,12 @@ nextflow_workflow { assertAll( { assert workflow.success}, { assert path(workflow.out.metrics.get(0).get(1)).getText().contains("97") }, + { assert workflow.out.per_sample_mqc_bundle.size() == 1 }, + { assert workflow.out.per_sample_mqc_bundle[0][0] == [ id:'test', single_end: false ] }, + { assert workflow.out.per_sample_mqc_bundle[0][1].size() == 4 }, { assert snapshot( path(workflow.out.bam[0][1]), - path(workflow.out.bai[0][1]), + path(workflow.out.index[0][1]), path(workflow.out.flagstat[0][1]), path(workflow.out.idxstats[0][1]), path(workflow.out.stats[0][1]) @@ -66,10 +66,7 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ]) """ @@ -80,9 +77,12 @@ nextflow_workflow { assertAll( { assert workflow.success}, { assert path(workflow.out.metrics.get(0).get(1)).getText().contains("0.999986") }, + { assert workflow.out.per_sample_mqc_bundle.size() == 1 }, + { assert workflow.out.per_sample_mqc_bundle[0][0] == [ id:'test' ] }, + { assert workflow.out.per_sample_mqc_bundle[0][1].size() == 4 }, { assert snapshot( file(workflow.out.cram[0][1]).name, - path(workflow.out.crai[0][1]), + path(workflow.out.index[0][1]), path(workflow.out.flagstat[0][1]), path(workflow.out.idxstats[0][1]), path(workflow.out.stats[0][1]) @@ -104,10 +104,7 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) """ @@ -135,10 +132,7 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ]) """ diff --git a/subworkflows/nf-core/bam_markduplicates_picard/tests/main.nf.test.snap b/subworkflows/nf-core/bam_markduplicates_picard/tests/main.nf.test.snap index bfa595e9..aab44024 100644 --- a/subworkflows/nf-core/bam_markduplicates_picard/tests/main.nf.test.snap +++ b/subworkflows/nf-core/bam_markduplicates_picard/tests/main.nf.test.snap @@ -5,13 +5,13 @@ "test.md.cram.crai:md5,b641c19be42d4841ec7155c686b70f39", "test.flagstat:md5,93b0ef463df947ede1f42ff60396c34d", "test.idxstats:md5,e179601fa7b8ebce81ac3765206f6c15", - "test.stats:md5,8ec963e4ee888c8cc9d41348cedd5106" + "test.stats:md5,e29d037f498c3e759a98641abf0e6028" ], - "timestamp": "2026-02-19T19:00:47.4418381", "meta": { - "nf-test": "0.9.4", + "nf-test": "0.9.3", "nextflow": "25.10.4" - } + }, + "timestamp": "2026-03-19T10:16:49.877108" }, "sarscov2 - bam - stub": { "content": [ @@ -47,12 +47,6 @@ ] ], "4": [ - - ], - "5": [ - - ], - "6": [ [ { "id": "test", @@ -61,7 +55,7 @@ "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "7": [ + "5": [ [ { "id": "test", @@ -70,7 +64,7 @@ "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" ] ], - "8": [ + "6": [ [ { "id": "test", @@ -79,13 +73,18 @@ "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "bai": [ + "7": [ [ { "id": "test", "single_end": false }, - "test.md.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.flagstat:md5,67394650dbae96d1a4fcc70484822159", + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], "bam": [ @@ -96,15 +95,9 @@ }, "test.md.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "crai": [ - ], "cram": [ - ], - "csi": [ - ], "flagstat": [ [ @@ -124,6 +117,15 @@ "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], + "index": [ + [ + { + "id": "test", + "single_end": false + }, + "test.md.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], "metrics": [ [ { @@ -133,6 +135,20 @@ "test.md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], + "per_sample_mqc_bundle": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.flagstat:md5,67394650dbae96d1a4fcc70484822159", + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], "stats": [ [ { @@ -144,11 +160,11 @@ ] } ], - "timestamp": "2026-02-19T19:00:56.802484512", "meta": { - "nf-test": "0.9.4", + "nf-test": "0.9.3", "nextflow": "25.10.4" - } + }, + "timestamp": "2026-04-20T10:50:34.652754" }, "homo_sapiens - cram - stub": { "content": [ @@ -173,9 +189,6 @@ ] ], "3": [ - - ], - "4": [ [ { "id": "test" @@ -183,10 +196,7 @@ "test.md.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "5": [ - - ], - "6": [ + "4": [ [ { "id": "test" @@ -194,7 +204,7 @@ "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "7": [ + "5": [ [ { "id": "test" @@ -202,7 +212,7 @@ "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" ] ], - "8": [ + "6": [ [ { "id": "test" @@ -210,19 +220,21 @@ "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "bai": [ - - ], - "bam": [ - - ], - "crai": [ + "7": [ [ { "id": "test" }, - "test.md.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.flagstat:md5,67394650dbae96d1a4fcc70484822159", + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] + ], + "bam": [ + ], "cram": [ [ @@ -231,9 +243,6 @@ }, "test.md.cram:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "csi": [ - ], "flagstat": [ [ @@ -251,6 +260,14 @@ "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], + "index": [ + [ + { + "id": "test" + }, + "test.md.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], "metrics": [ [ { @@ -259,6 +276,19 @@ "test.md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], + "per_sample_mqc_bundle": [ + [ + { + "id": "test" + }, + [ + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.flagstat:md5,67394650dbae96d1a4fcc70484822159", + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.md.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], "stats": [ [ { @@ -269,11 +299,11 @@ ] } ], - "timestamp": "2026-02-19T19:01:05.884074864", "meta": { - "nf-test": "0.9.4", + "nf-test": "0.9.3", "nextflow": "25.10.4" - } + }, + "timestamp": "2026-04-20T10:51:10.962305" }, "sarscov2 - bam": { "content": [ @@ -281,12 +311,12 @@ "test.md.bam.bai:md5,8973dd987f3ac6c352716ef89139c567", "test.flagstat:md5,4f7ffd1e6a5e85524d443209ac97d783", "test.idxstats:md5,df60a8c8d6621100d05178c93fb053a2", - "test.stats:md5,950c07a54b20e443105a5391400a4c92" + "test.stats:md5,fe8e692d2560dcfd556405b987c9033c" ], - "timestamp": "2026-02-19T19:00:36.539092187", "meta": { - "nf-test": "0.9.4", + "nf-test": "0.9.3", "nextflow": "25.10.4" - } + }, + "timestamp": "2026-03-19T10:16:24.606155" } } \ No newline at end of file diff --git a/subworkflows/nf-core/bam_sort_stats_samtools/main.nf b/subworkflows/nf-core/bam_sort_stats_samtools/main.nf index 312c2d24..d0cd8c30 100644 --- a/subworkflows/nf-core/bam_sort_stats_samtools/main.nf +++ b/subworkflows/nf-core/bam_sort_stats_samtools/main.nf @@ -8,35 +8,24 @@ include { BAM_STATS_SAMTOOLS } from '../bam_stats_samtools/main' workflow BAM_SORT_STATS_SAMTOOLS { take: - ch_bam // channel: [ val(meta), [ bam ] ] - ch_fasta // channel: [ val(meta), path(fasta) ] + ch_bam // channel: [ val(meta), [ bam ] ] + ch_fasta_fai // channel: [ val(meta), path(fasta), path(fai) ] main: - SAMTOOLS_SORT ( ch_bam, ch_fasta, '' ) + SAMTOOLS_SORT(ch_bam, ch_fasta_fai, '') - SAMTOOLS_INDEX ( SAMTOOLS_SORT.out.bam ) + SAMTOOLS_INDEX(SAMTOOLS_SORT.out.bam) SAMTOOLS_SORT.out.bam - .join(SAMTOOLS_INDEX.out.bai, by: [0], remainder: true) - .join(SAMTOOLS_INDEX.out.csi, by: [0], remainder: true) - .map { - meta, bam, bai, csi -> - if (bai) { - [ meta, bam, bai ] - } else { - [ meta, bam, csi ] - } - } + .join(SAMTOOLS_INDEX.out.index, by: [0]) .set { ch_bam_bai } - BAM_STATS_SAMTOOLS ( ch_bam_bai, ch_fasta ) + BAM_STATS_SAMTOOLS(ch_bam_bai, ch_fasta_fai) emit: - bam = SAMTOOLS_SORT.out.bam // channel: [ val(meta), [ bam ] ] - bai = SAMTOOLS_INDEX.out.bai // channel: [ val(meta), [ bai ] ] - csi = SAMTOOLS_INDEX.out.csi // channel: [ val(meta), [ csi ] ] - - stats = BAM_STATS_SAMTOOLS.out.stats // channel: [ val(meta), [ stats ] ] + bam = SAMTOOLS_SORT.out.bam // channel: [ val(meta), [ bam ] ] + index = SAMTOOLS_INDEX.out.index // channel: [ val(meta), [ index ] ] + stats = BAM_STATS_SAMTOOLS.out.stats // channel: [ val(meta), [ stats ] ] flagstat = BAM_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), [ flagstat ] ] idxstats = BAM_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), [ idxstats ] ] } diff --git a/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test b/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test index c5841289..2db95965 100644 --- a/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test +++ b/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test @@ -27,7 +27,8 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) """ } @@ -37,7 +38,7 @@ nextflow_workflow { assertAll( { assert workflow.success}, { assert workflow.out.bam.get(0).get(1) ==~ ".*.bam"}, - { assert workflow.out.bai.get(0).get(1) ==~ ".*.bai"}, + { assert workflow.out.index.get(0).get(1) ==~ ".*.bai"}, { assert snapshot( workflow.out.flagstat, workflow.out.idxstats, @@ -57,7 +58,8 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) """ } @@ -67,7 +69,7 @@ nextflow_workflow { assertAll( { assert workflow.success}, { assert workflow.out.bam.get(0).get(1) ==~ ".*.bam"}, - { assert workflow.out.bai.get(0).get(1) ==~ ".*.bai"}, + { assert workflow.out.index.get(0).get(1) ==~ ".*.bai"}, { assert snapshot( workflow.out.flagstat, workflow.out.idxstats, @@ -89,7 +91,8 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) """ } @@ -116,7 +119,8 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) """ } diff --git a/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test.snap b/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test.snap index f62d68c9..d2ed2c25 100644 --- a/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test.snap +++ b/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test.snap @@ -25,15 +25,15 @@ "id": "test", "single_end": false }, - "test.stats:md5,1101fe711c4a389fdb5c4a1532107d1f" + "test.stats:md5,0d0496957cd3bae8f557f2e9f6876a46" ] ] ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.3" + "nextflow": "25.10.4" }, - "timestamp": "2026-02-03T11:33:01.647190952" + "timestamp": "2026-03-19T09:55:29.570804" }, "test_bam_sort_stats_samtools_paired_end": { "content": [ @@ -61,15 +61,15 @@ "id": "test", "single_end": false }, - "test.stats:md5,f26c554c244ee86c89d62ebed509fd95" + "test.stats:md5,12b526148cc9b6ffa8893903f65f19fc" ] ] ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.3" + "nextflow": "25.10.4" }, - "timestamp": "2026-02-03T11:33:08.706742267" + "timestamp": "2026-03-19T09:55:39.804101" }, "test_bam_sort_stats_samtools_single_end - stub": { "content": [ @@ -93,9 +93,6 @@ ] ], "2": [ - - ], - "3": [ [ { "id": "test", @@ -104,7 +101,7 @@ "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "4": [ + "3": [ [ { "id": "test", @@ -113,7 +110,7 @@ "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" ] ], - "5": [ + "4": [ [ { "id": "test", @@ -122,43 +119,40 @@ "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "bai": [ + "bam": [ [ { "id": "test", "single_end": false }, - "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "bam": [ + "flagstat": [ [ { "id": "test", "single_end": false }, - "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" ] ], - "csi": [ - - ], - "flagstat": [ + "idxstats": [ [ { "id": "test", "single_end": false }, - "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "idxstats": [ + "index": [ [ { "id": "test", "single_end": false }, - "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "stats": [ @@ -174,9 +168,9 @@ ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.3" + "nextflow": "25.10.4" }, - "timestamp": "2026-02-03T11:11:02.1412136" + "timestamp": "2026-03-12T15:01:02.797853" }, "test_bam_sort_stats_samtools_paired_end - stub": { "content": [ @@ -200,9 +194,6 @@ ] ], "2": [ - - ], - "3": [ [ { "id": "test", @@ -211,7 +202,7 @@ "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "4": [ + "3": [ [ { "id": "test", @@ -220,7 +211,7 @@ "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" ] ], - "5": [ + "4": [ [ { "id": "test", @@ -229,43 +220,40 @@ "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "bai": [ + "bam": [ [ { "id": "test", "single_end": false }, - "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "bam": [ + "flagstat": [ [ { "id": "test", "single_end": false }, - "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" ] ], - "csi": [ - - ], - "flagstat": [ + "idxstats": [ [ { "id": "test", "single_end": false }, - "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "idxstats": [ + "index": [ [ { "id": "test", "single_end": false }, - "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "stats": [ @@ -281,8 +269,8 @@ ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.3" + "nextflow": "25.10.4" }, - "timestamp": "2026-02-03T11:11:09.165267895" + "timestamp": "2026-03-12T15:01:13.722701" } } \ No newline at end of file diff --git a/subworkflows/nf-core/bam_stats_samtools/main.nf b/subworkflows/nf-core/bam_stats_samtools/main.nf index 34e8fe10..14545ba2 100644 --- a/subworkflows/nf-core/bam_stats_samtools/main.nf +++ b/subworkflows/nf-core/bam_stats_samtools/main.nf @@ -9,17 +9,17 @@ include { SAMTOOLS_FLAGSTAT } from '../../../modules/nf-core/samtools/flagstat/m workflow BAM_STATS_SAMTOOLS { take: ch_bam_bai // channel: [ val(meta), path(bam), path(bai) ] - ch_fasta // channel: [ val(meta), path(fasta) ] + ch_fasta_fai // channel: [ val(meta), path(fasta) ] main: - SAMTOOLS_STATS ( ch_bam_bai, ch_fasta ) + SAMTOOLS_STATS(ch_bam_bai, ch_fasta_fai) - SAMTOOLS_FLAGSTAT ( ch_bam_bai ) + SAMTOOLS_FLAGSTAT(ch_bam_bai) - SAMTOOLS_IDXSTATS ( ch_bam_bai ) + SAMTOOLS_IDXSTATS(ch_bam_bai) emit: - stats = SAMTOOLS_STATS.out.stats // channel: [ val(meta), path(stats) ] + stats = SAMTOOLS_STATS.out.stats // channel: [ val(meta), path(stats) ] flagstat = SAMTOOLS_FLAGSTAT.out.flagstat // channel: [ val(meta), path(flagstat) ] idxstats = SAMTOOLS_IDXSTATS.out.idxstats // channel: [ val(meta), path(idxstats) ] } diff --git a/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test b/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test index 2f329695..8ec544b9 100644 --- a/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test +++ b/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test @@ -24,7 +24,8 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) """ } @@ -53,7 +54,8 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) """ } @@ -82,7 +84,8 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ]) """ } @@ -113,7 +116,8 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) """ } @@ -141,7 +145,8 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ]) """ } @@ -169,7 +174,8 @@ nextflow_workflow { ]) input[1] = Channel.of([ [ id:'genome' ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) ]) """ } diff --git a/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test.snap b/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test.snap index 9c8ff1b5..5a4a01f9 100644 --- a/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test.snap +++ b/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test.snap @@ -220,15 +220,15 @@ "id": "test", "single_end": true }, - "test.stats:md5,7a05a22bdb17e8df6e8c2d100ff09a31" + "test.stats:md5,afd73326205e0995268b7a796d93139e" ] ] ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.3" + "nextflow": "25.10.4" }, - "timestamp": "2026-02-03T11:32:20.243663217" + "timestamp": "2026-03-19T10:42:09.4463" }, "test_bam_stats_samtools_paired_end": { "content": [ @@ -256,15 +256,15 @@ "id": "test", "single_end": true }, - "test.stats:md5,a391612b5ef5b181e854ccaad8c8a068" + "test.stats:md5,681ce95af0c57dc36c647f2157c17b6a" ] ] ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.3" + "nextflow": "25.10.4" }, - "timestamp": "2026-02-03T11:32:26.434187887" + "timestamp": "2026-03-19T10:42:15.787592" }, "test_bam_stats_samtools_paired_end_cram": { "content": [ @@ -292,14 +292,14 @@ "id": "test", "single_end": false }, - "test.stats:md5,2b0e31ab01b867a6ff312023ae03838d" + "test.stats:md5,96020b0280addb09a48c63a5d510fc15" ] ] ], "meta": { "nf-test": "0.9.3", - "nextflow": "25.10.3" + "nextflow": "25.10.4" }, - "timestamp": "2026-02-03T11:32:32.441454186" + "timestamp": "2026-03-19T10:42:22.199498" } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_align_bowtie2/main.nf b/subworkflows/nf-core/fastq_align_bowtie2/main.nf index 8cbc5141..8c1a19f5 100644 --- a/subworkflows/nf-core/fastq_align_bowtie2/main.nf +++ b/subworkflows/nf-core/fastq_align_bowtie2/main.nf @@ -7,37 +7,35 @@ include { BAM_SORT_STATS_SAMTOOLS } from '../bam_sort_stats_samtools/main' workflow FASTQ_ALIGN_BOWTIE2 { take: - ch_reads // channel: [ val(meta), [ reads ] ] - ch_index // channel: /path/to/bowtie2/index/ - save_unaligned // val - sort_bam // val - ch_fasta // channel: /path/to/reference.fasta + ch_reads // channel: [ val(meta), [ reads ] ] + ch_index // channel: /path/to/bowtie2/index/ + save_unaligned // val + sort_bam // val + ch_fasta_fai // channel: [ val(meta), path(fasta), path(fai) ] main: - ch_versions = channel.empty() + // + // Remap ch_fasta_fai to ch_fasta + ch_fasta = ch_fasta_fai.map{ meta, fasta, _fai -> [ meta, fasta] } // // Map reads with Bowtie2 // - BOWTIE2_ALIGN ( ch_reads, ch_index, ch_fasta, save_unaligned, sort_bam ) + BOWTIE2_ALIGN(ch_reads, ch_index, ch_fasta, save_unaligned, sort_bam) // // Sort, index BAM file and run samtools stats, flagstat and idxstats // - BAM_SORT_STATS_SAMTOOLS ( BOWTIE2_ALIGN.out.bam, ch_fasta ) + BAM_SORT_STATS_SAMTOOLS(BOWTIE2_ALIGN.out.bam, ch_fasta_fai) emit: - bam_orig = BOWTIE2_ALIGN.out.bam // channel: [ val(meta), aligned ] - log_out = BOWTIE2_ALIGN.out.log // channel: [ val(meta), log ] - fastq = BOWTIE2_ALIGN.out.fastq // channel: [ val(meta), fastq ] - - bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), [ bam ] ] - bai = BAM_SORT_STATS_SAMTOOLS.out.bai // channel: [ val(meta), [ bai ] ] - csi = BAM_SORT_STATS_SAMTOOLS.out.csi // channel: [ val(meta), [ csi ] ] - stats = BAM_SORT_STATS_SAMTOOLS.out.stats // channel: [ val(meta), [ stats ] ] - flagstat = BAM_SORT_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), [ flagstat ] ] - idxstats = BAM_SORT_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), [ idxstats ] ] - - versions = ch_versions // channel: [ versions.yml ] + bam_orig = BOWTIE2_ALIGN.out.bam // channel: [ val(meta), aligned ] + log_out = BOWTIE2_ALIGN.out.log // channel: [ val(meta), log ] + fastq = BOWTIE2_ALIGN.out.fastq // channel: [ val(meta), fastq ] + bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), [ bam ] ] + index = BAM_SORT_STATS_SAMTOOLS.out.index // channel: [ val(meta), [ index ] ] + stats = BAM_SORT_STATS_SAMTOOLS.out.stats // channel: [ val(meta), [ stats ] ] + flagstat = BAM_SORT_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), [ flagstat ] ] + idxstats = BAM_SORT_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), [ idxstats ] ] } diff --git a/subworkflows/nf-core/fastq_align_bowtie2/meta.yml b/subworkflows/nf-core/fastq_align_bowtie2/meta.yml index b18e4054..096df347 100644 --- a/subworkflows/nf-core/fastq_align_bowtie2/meta.yml +++ b/subworkflows/nf-core/fastq_align_bowtie2/meta.yml @@ -39,20 +39,16 @@ input: description: | Use samtools sort (true) or samtools view (false) default: false - - ch_fasta: + - ch_fasta_fai: type: file - description: Reference fasta file - pattern: "*.{fasta,fa}" + description: Reference fasta file and index + pattern: "*.{fasta,fa},*.{fai,fai}" # TODO Update when we decide on a standard for subworkflow docs output: - bam: type: file description: Output BAM file containing read alignments pattern: "*.{bam}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - fastq: type: file description: Unaligned FastQ files diff --git a/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test b/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test index 6eca398d..975a2399 100644 --- a/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test @@ -19,7 +19,10 @@ nextflow_workflow { script "../../../../modules/nf-core/bowtie2/build/main.nf" process { """ - input[0] = Channel.value([ [ id:'genome' ],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]) + input[0] = Channel.value([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) """ } } @@ -31,7 +34,11 @@ nextflow_workflow { input[1] = BOWTIE2_BUILD.out.index input[2] = false input[3] = false - input[4] = Channel.value([ [ id:'genome' ],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]) + input[4] = Channel.value([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ]) """ } } @@ -44,8 +51,7 @@ nextflow_workflow { workflow.out.fastq, workflow.out.log_out, file(workflow.out.bam[0][1]).name, - file(workflow.out.bai[0][1]).name, - workflow.out.csi, + file(workflow.out.index[0][1]).name, workflow.out.stats, workflow.out.flagstat, workflow.out.idxstats, @@ -61,7 +67,10 @@ nextflow_workflow { script "../../../../modules/nf-core/bowtie2/build/main.nf" process { """ - input[0] = Channel.value([ [ id:'genome' ],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]) + input[0] = Channel.value([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) """ } } @@ -69,11 +78,19 @@ nextflow_workflow { when { 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[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] = BOWTIE2_BUILD.out.index input[2] = false input[3] = false - input[4] = Channel.value([ [ id:'genome' ],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]) + input[4] = Channel.value([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ]) """ } } @@ -86,8 +103,7 @@ nextflow_workflow { workflow.out.fastq, workflow.out.log_out, file(workflow.out.bam[0][1]).name, - file(workflow.out.bai[0][1]).name, - workflow.out.csi, + file(workflow.out.index[0][1]).name, workflow.out.stats, workflow.out.flagstat, workflow.out.idxstats, @@ -106,7 +122,10 @@ nextflow_workflow { script "../../../../modules/nf-core/bowtie2/build/main.nf" process { """ - input[0] = Channel.value([ [ id:'genome' ],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]) + input[0] = Channel.value([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) """ } } @@ -118,7 +137,11 @@ nextflow_workflow { input[1] = BOWTIE2_BUILD.out.index input[2] = false input[3] = false - input[4] = Channel.value([ [ id:'genome' ],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]) + input[4] = Channel.value([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ]) """ } } @@ -131,8 +154,7 @@ nextflow_workflow { workflow.out.fastq, workflow.out.log_out, file(workflow.out.bam[0][1]).name, - file(workflow.out.bai[0][1]).name, - workflow.out.csi, + file(workflow.out.index[0][1]).name, workflow.out.stats, workflow.out.flagstat, workflow.out.idxstats, @@ -151,7 +173,10 @@ nextflow_workflow { script "../../../../modules/nf-core/bowtie2/build/main.nf" process { """ - input[0] = Channel.value([ [ id:'genome' ],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]) + input[0] = Channel.value([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) """ } } @@ -163,7 +188,11 @@ nextflow_workflow { input[1] = BOWTIE2_BUILD.out.index input[2] = false input[3] = false - input[4] = Channel.value([ [ id:'genome' ],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]) + input[4] = Channel.value([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ]) """ } } @@ -176,8 +205,7 @@ nextflow_workflow { workflow.out.fastq, workflow.out.log_out, file(workflow.out.bam[0][1]).name, - file(workflow.out.bai[0][1]).name, - workflow.out.csi, + file(workflow.out.index[0][1]).name, workflow.out.stats, workflow.out.flagstat, workflow.out.idxstats, diff --git a/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test.snap index 2dc8896b..d5d94b71 100644 --- a/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test.snap @@ -16,9 +16,6 @@ ], "test.sorted.bam", "test.sorted.bam.bai", - [ - - ], [ [ { @@ -46,15 +43,13 @@ "test.sorted.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - [ - - ] + null ], + "timestamp": "2026-03-12T15:08:47.079633947", "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.3" - }, - "timestamp": "2026-02-03T15:14:25.504699933" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_align_bowtie2_single_end": { "content": [ @@ -73,16 +68,13 @@ ], "test.sorted.bam", "test.sorted.bam.bai", - [ - - ], [ [ { "id": "test", "single_end": true }, - "test.sorted.stats:md5,48b911852e91d77db59154f7355ede4f" + "test.sorted.stats:md5,de68b1a4ae60b97305ae3423e11813ad" ] ], [ @@ -103,15 +95,13 @@ "test.sorted.idxstats:md5,e16eb632f7f462514b0873c7ac8ac905" ] ], - [ - - ] + null ], + "timestamp": "2026-04-12T00:04:56.432243", "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.3" - }, - "timestamp": "2026-02-03T15:14:08.108143527" + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } }, "test_align_bowtie2_paired_end": { "content": [ @@ -130,16 +120,13 @@ ], "test.sorted.bam", "test.sorted.bam.bai", - [ - - ], [ [ { "id": "test", "single_end": false }, - "test.sorted.stats:md5,cb422b3fcd4327488cb6bc5ac15a48ff" + "test.sorted.stats:md5,4cb22b98cb1bbecb025088f7f5e13e11" ] ], [ @@ -160,15 +147,13 @@ "test.sorted.idxstats:md5,29ff2fa56d35b2a47625b8f517f1a947" ] ], - [ - - ] + null ], + "timestamp": "2026-04-12T00:05:09.593942", "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.3" - }, - "timestamp": "2026-02-03T15:14:17.07821488" + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } }, "test_align_bowtie2_paired_end - stub": { "content": [ @@ -187,9 +172,6 @@ ], "test.sorted.bam", "test.sorted.bam.bai", - [ - - ], [ [ { @@ -217,14 +199,12 @@ "test.sorted.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - [ - - ] + null ], + "timestamp": "2026-03-12T15:08:58.246336497", "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.3" - }, - "timestamp": "2026-02-03T15:14:34.088967148" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_align_bwa/main.nf b/subworkflows/nf-core/fastq_align_bwa/main.nf index e06a5fab..eb72bade 100644 --- a/subworkflows/nf-core/fastq_align_bwa/main.nf +++ b/subworkflows/nf-core/fastq_align_bwa/main.nf @@ -7,35 +7,30 @@ include { BAM_SORT_STATS_SAMTOOLS } from '../bam_sort_stats_samtools/main' workflow FASTQ_ALIGN_BWA { take: - ch_reads // channel (mandatory): [ val(meta), [ path(reads) ] ] - ch_index // channel (mandatory): [ val(meta2), path(index) ] - val_sort_bam // boolean (mandatory): true or false - ch_fasta // channel (optional) : [ val(meta3), path(fasta) ] + ch_reads // channel (mandatory): [ val(meta), [ path(reads) ] ] + ch_index // channel (mandatory): [ val(meta2), path(index) ] + val_sort_bam // boolean (mandatory): true or false + ch_fasta_fai // channel (optional) : [ val(meta3), path(fasta), path(fai) ] main: - ch_versions = channel.empty() // // Map reads with BWA // - - BWA_MEM ( ch_reads, ch_index, ch_fasta, val_sort_bam ) + ch_fasta = ch_fasta_fai.map { meta, fasta, _fai -> [meta, fasta] } + BWA_MEM(ch_reads, ch_index, ch_fasta, val_sort_bam) // // Sort, index BAM file and run samtools stats, flagstat and idxstats // - BAM_SORT_STATS_SAMTOOLS ( BWA_MEM.out.bam, ch_fasta ) + BAM_SORT_STATS_SAMTOOLS(BWA_MEM.out.bam, ch_fasta_fai) emit: - bam_orig = BWA_MEM.out.bam // channel: [ val(meta), path(bam) ] - - bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), path(bam) ] - bai = BAM_SORT_STATS_SAMTOOLS.out.bai // channel: [ val(meta), path(bai) ] - csi = BAM_SORT_STATS_SAMTOOLS.out.csi // channel: [ val(meta), path(csi) ] - stats = BAM_SORT_STATS_SAMTOOLS.out.stats // channel: [ val(meta), path(stats) ] + bam_orig = BWA_MEM.out.bam // channel: [ val(meta), path(bam) ] + bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), path(bam) ] + index = BAM_SORT_STATS_SAMTOOLS.out.index // channel: [ val(meta), path(index) ] + stats = BAM_SORT_STATS_SAMTOOLS.out.stats // channel: [ val(meta), path(stats) ] flagstat = BAM_SORT_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), path(flagstat) ] idxstats = BAM_SORT_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), path(idxstats) ] - - versions = ch_versions // channel: [ path(versions.yml) ] } diff --git a/subworkflows/nf-core/fastq_align_bwa/meta.yml b/subworkflows/nf-core/fastq_align_bwa/meta.yml index fa218408..12569fa3 100644 --- a/subworkflows/nf-core/fastq_align_bwa/meta.yml +++ b/subworkflows/nf-core/fastq_align_bwa/meta.yml @@ -29,11 +29,11 @@ input: type: boolean description: If true bwa modules sort resulting bam files pattern: "true|false" - - ch_fasta: + - ch_fasta_fai: type: file description: | - Optional reference fasta file. This only needs to be given if val_sort_bam = true. - Structure: [ val(meta), path(fasta) ] + Optional reference fasta file and index. This only needs to be given if val_sort_bam = true. + Structure: [ val(meta), path(fasta), path(fai) ] output: - bam_orig: description: | @@ -63,10 +63,6 @@ output: description: | File containing samtools idxstats output Structure: [ val(meta), path(idxstats) ] - - versions: - description: | - Files containing software versions - Structure: [ path(versions.yml) ] authors: - "@JoseEspinosa" maintainers: diff --git a/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test b/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test index 7262325a..491c8fdd 100644 --- a/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test @@ -31,7 +31,7 @@ nextflow_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] = BWA_INDEX.out.index input[2] = false - input[3] = Channel.value([[id: 'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]) + input[3] = Channel.value([[id: 'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]) """ } } @@ -62,7 +62,7 @@ nextflow_workflow { ] ) input[1] = BWA_INDEX.out.index input[2] = false - input[3] = Channel.value([[id: 'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]) + input[3] = Channel.value([[id: 'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]) """ } } diff --git a/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test.snap index 9a16da29..445876c2 100644 --- a/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test.snap @@ -17,7 +17,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,ba4b90f87517a16a6ae6142f37a75d79" + "test.sorted.bam:md5,8ad8cbe24a043b395cbb49ad3f88cc18" ] ], "2": [ @@ -26,22 +26,19 @@ "id": "test", "single_end": false }, - "test.sorted.bam.bai:md5,4c5e6fa0e71327b79034eebd652f2121" + "test.sorted.bam.bai:md5,4e57a761d8cee868242b4874b95b4691" ] ], "3": [ - - ], - "4": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam.stats:md5,75934f2a51780a80d2ab4674301a018d" + "test.sorted.bam.stats:md5,21b91a04b74c3498ebb73d185a2bfc95" ] ], - "5": [ + "4": [ [ { "id": "test", @@ -50,7 +47,7 @@ "test.sorted.bam.flagstat:md5,18d602435a02a4d721b78d1812622159" ] ], - "6": [ + "5": [ [ { "id": "test", @@ -59,25 +56,13 @@ "test.sorted.bam.idxstats:md5,85d20a901eef23ca50c323638a2eb602" ] ], - "7": [ - - ], - "bai": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam.bai:md5,4c5e6fa0e71327b79034eebd652f2121" - ] - ], "bam": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam:md5,ba4b90f87517a16a6ae6142f37a75d79" + "test.sorted.bam:md5,8ad8cbe24a043b395cbb49ad3f88cc18" ] ], "bam_orig": [ @@ -88,9 +73,6 @@ }, "test.bam:md5,5dbdcfdba65fac634dcbb6984cffe2c4" ] - ], - "csi": [ - ], "flagstat": [ [ @@ -110,25 +92,31 @@ "test.sorted.bam.idxstats:md5,85d20a901eef23ca50c323638a2eb602" ] ], - "stats": [ + "index": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam.stats:md5,75934f2a51780a80d2ab4674301a018d" + "test.sorted.bam.bai:md5,4e57a761d8cee868242b4874b95b4691" ] ], - "versions": [ - + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,21b91a04b74c3498ebb73d185a2bfc95" + ] ] } ], - "timestamp": "2026-02-18T12:47:43.306112", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.10.4" - } + "nf-test": "0.9.3", + "nextflow": "25.10.1" + }, + "timestamp": "2026-04-29T11:14:26.020303576" }, "fastq_align_bwa_single_end": { "content": [ @@ -148,7 +136,7 @@ "id": "test", "single_end": true }, - "test.sorted.bam:md5,c406a43adde2d9673e71d8a8c7db7cfd" + "test.sorted.bam:md5,00b7c143a13d0881b6d0ef0f4f8665ae" ] ], "2": [ @@ -157,22 +145,19 @@ "id": "test", "single_end": true }, - "test.sorted.bam.bai:md5,f79a40341ecfaae11d8621b138d4c2ea" + "test.sorted.bam.bai:md5,9257847727b20a8f7288ad6912fbada4" ] ], "3": [ - - ], - "4": [ [ { "id": "test", "single_end": true }, - "test.sorted.bam.stats:md5,0883b19c92a783883b3e11d5bfcc5d6a" + "test.sorted.bam.stats:md5,28f7879551f22fca1e2c788f1eb712d8" ] ], - "5": [ + "4": [ [ { "id": "test", @@ -181,7 +166,7 @@ "test.sorted.bam.flagstat:md5,2191911d72575a2358b08b1df64ccb53" ] ], - "6": [ + "5": [ [ { "id": "test", @@ -190,25 +175,13 @@ "test.sorted.bam.idxstats:md5,613e048487662c694aa4a2f73ca96a20" ] ], - "7": [ - - ], - "bai": [ - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam.bai:md5,f79a40341ecfaae11d8621b138d4c2ea" - ] - ], "bam": [ [ { "id": "test", "single_end": true }, - "test.sorted.bam:md5,c406a43adde2d9673e71d8a8c7db7cfd" + "test.sorted.bam:md5,00b7c143a13d0881b6d0ef0f4f8665ae" ] ], "bam_orig": [ @@ -219,9 +192,6 @@ }, "test.bam:md5,f7af092ddd5203f647ba96b926392c3e" ] - ], - "csi": [ - ], "flagstat": [ [ @@ -241,24 +211,30 @@ "test.sorted.bam.idxstats:md5,613e048487662c694aa4a2f73ca96a20" ] ], - "stats": [ + "index": [ [ { "id": "test", "single_end": true }, - "test.sorted.bam.stats:md5,0883b19c92a783883b3e11d5bfcc5d6a" + "test.sorted.bam.bai:md5,9257847727b20a8f7288ad6912fbada4" ] ], - "versions": [ - + "stats": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.stats:md5,28f7879551f22fca1e2c788f1eb712d8" + ] ] } ], - "timestamp": "2026-02-18T12:47:30.203617", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.10.4" - } + "nf-test": "0.9.3", + "nextflow": "25.10.1" + }, + "timestamp": "2026-04-29T11:14:09.893784807" } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_align_chromap/main.nf b/subworkflows/nf-core/fastq_align_chromap/main.nf index 549579fa..c346adba 100644 --- a/subworkflows/nf-core/fastq_align_chromap/main.nf +++ b/subworkflows/nf-core/fastq_align_chromap/main.nf @@ -2,39 +2,55 @@ * Map reads, sort, index BAM file and run samtools stats, flagstat and idxstats */ -include { CHROMAP_CHROMAP } from '../../../modules/nf-core/chromap/chromap/main' -include { BAM_SORT_STATS_SAMTOOLS } from '../bam_sort_stats_samtools/main' +include { CHROMAP_CHROMAP } from '../../../modules/nf-core/chromap/chromap/main' +include { PICARD_ADDORREPLACEREADGROUPS } from '../../../modules/nf-core/picard/addorreplacereadgroups/main' +include { BAM_SORT_STATS_SAMTOOLS } from '../bam_sort_stats_samtools/main' workflow FASTQ_ALIGN_CHROMAP { take: - ch_reads // channel (mandatory): [ val(meta), [ reads ] ] - ch_index // channel (mandatory): [ val(meta2, [ index ] ] - ch_fasta // channel (mandatory): [ val(meta2, [ fasta ] ] - ch_barcodes // channel (optional): [ barcodes ] - ch_whitelist // channel (optional): [ whitelist ] - ch_chr_order // channel (optional): [ chr_order ] + ch_reads // channel (mandatory): [ val(meta), [ reads ] ] + ch_index // channel (mandatory): [ val(meta2, [ index ] ] + ch_fasta_fai // channel (mandatory): [ val(meta2, [ fasta ], [ fai ] ] + ch_barcodes // channel (optional): [ barcodes ] + ch_whitelist // channel (optional): [ whitelist ] + ch_chr_order // channel (optional): [ chr_order ] ch_pairs_chr_order // channel (optional): [ pairs_chr_order ] + update_readgroups // boolean (optional): true or false controls whether readgroups should be updated post alignment main: - ch_versions = channel.empty() + + ch_bam = channel.empty() + def add_readgroups = update_readgroups ?: false + + // + // Remap ch_fasta_fai to ch_fasta + // + ch_fasta = ch_fasta_fai.map { meta, fasta , _fai -> [ meta, fasta ] } // // Map reads with CHROMAP // CHROMAP_CHROMAP(ch_reads, ch_fasta, ch_index, ch_barcodes, ch_whitelist, ch_chr_order, ch_pairs_chr_order) - ch_versions = ch_versions.mix(CHROMAP_CHROMAP.out.versions) + + // + // If needed update read groups + // + if (add_readgroups) { + PICARD_ADDORREPLACEREADGROUPS(CHROMAP_CHROMAP.out.bam, ch_fasta_fai) + ch_bam = PICARD_ADDORREPLACEREADGROUPS.out.bam + } else { + ch_bam = CHROMAP_CHROMAP.out.bam + } // // Sort, index BAM file and run samtools stats, flagstat and idxstats // - BAM_SORT_STATS_SAMTOOLS(CHROMAP_CHROMAP.out.bam, ch_fasta) + BAM_SORT_STATS_SAMTOOLS(ch_bam, ch_fasta_fai) emit: - bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), [ bam ] ] - bai = BAM_SORT_STATS_SAMTOOLS.out.bai // channel: [ val(meta), [ bai ] ] - stats = BAM_SORT_STATS_SAMTOOLS.out.stats // channel: [ val(meta), [ stats ] ] - flagstat = BAM_SORT_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), [ flagstat ] ] - idxstats = BAM_SORT_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), [ idxstats ] ] - - versions = ch_versions // path: versions.yml + bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), [ bam ] ] + index = BAM_SORT_STATS_SAMTOOLS.out.index // channel: [ val(meta), [ index ] ] + stats = BAM_SORT_STATS_SAMTOOLS.out.stats // channel: [ val(meta), [ stats ] ] + flagstat = BAM_SORT_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), [ flagstat ] ] + idxstats = BAM_SORT_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), [ idxstats ] ] } diff --git a/subworkflows/nf-core/fastq_align_chromap/meta.yml b/subworkflows/nf-core/fastq_align_chromap/meta.yml index 1db3eff1..f433cabb 100644 --- a/subworkflows/nf-core/fastq_align_chromap/meta.yml +++ b/subworkflows/nf-core/fastq_align_chromap/meta.yml @@ -1,6 +1,6 @@ # yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json name: "fastq_align_chromap" -description: Align high throughput chromatin profiles using Chromap then sort with samtools +description: Align high throughput chromatin profiles using Chromap, updating readgroups if neccessary and then sort with samtools keywords: - align - fasta @@ -12,6 +12,7 @@ keywords: - hic components: - chromap/chromap + - picard/addorreplacereadgroups - samtools/sort - samtools/index - samtools/stats @@ -41,12 +42,12 @@ input: Structure: [val(meta2), path(index)] Chromap genome index files pattern: "*.index" - - ch_fasta: + - ch_fasta_fai: type: file description: | - Structure: [val(meta2), path(fasta)] - Reference fasta file - pattern: "*.{fasta,fa}" + Structure: [val(meta2), path(fasta), path(fai)] + Reference fasta file and index + pattern: "*.{fasta,fa},*.fai" - ch_barcodes: type: file description: | @@ -67,6 +68,11 @@ input: description: | Structure: [path(pairs_chr_order)] Natural chromosome order for pairs flipping + - update_readgroups: + type: boolean + description: | + Boolean controling whether the readgroups should be added or updated + after chromap alignment output: - meta: type: map diff --git a/subworkflows/nf-core/fastq_align_chromap/tests/main.nf.test b/subworkflows/nf-core/fastq_align_chromap/tests/main.nf.test index 25001bcf..41b2209c 100644 --- a/subworkflows/nf-core/fastq_align_chromap/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_align_chromap/tests/main.nf.test @@ -10,6 +10,7 @@ nextflow_workflow { tag "chromap" tag "chromap/chromap" tag "chromap/index" + tag "picard/addorreplacereadgroups" tag "fastq_align_chromap" tag "subworkflows/fastq_align_chromap" tag "subworkflows/bam_sort_stats_samtools" @@ -39,22 +40,25 @@ nextflow_workflow { input[1] = CHROMAP_INDEX.out.index input[2] = Channel.of([ [id:'test'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists:true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists:true) ]) input[3] = [] input[4] = [] input[5] = [] input[6] = [] + input[7] = false """ } } then { assertAll( { assert workflow.success }, - { assert snapshot(workflow.out).match() } + { assert snapshot(sanitizeOutput(workflow.out)).match() } ) } } + test("test_fastq_align_chromap_paired_end") { when { workflow { @@ -69,19 +73,84 @@ nextflow_workflow { input[1] = CHROMAP_INDEX.out.index input[2] = Channel.of([ [id:'test'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists:true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists:true) ]) input[3] = [] input[4] = [] input[5] = [] input[6] = [] + input[7] = false """ } } then { assertAll( { assert workflow.success }, - { assert snapshot(workflow.out).match() } + { assert snapshot(sanitizeOutput(workflow.out)).match() } + ) + } + } + + test("test_fastq_align_chromap_single_end_add_readgroups") { + 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] = CHROMAP_INDEX.out.index + input[2] = Channel.of([ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists:true) + ]) + input[3] = [] + input[4] = [] + input[5] = [] + input[6] = [] + input[7] = true + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot(sanitizeOutput(workflow.out)).match() } + ) + } + } + + test("test_fastq_align_chromap_paired_end_add_readgroups") { + when { + 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] = CHROMAP_INDEX.out.index + input[2] = Channel.of([ + [id:'test'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists:true) + ]) + input[3] = [] + input[4] = [] + input[5] = [] + input[6] = [] + input[7] = true + """ + } + } + then { + assertAll( + { assert workflow.success }, + { assert snapshot(sanitizeOutput(workflow.out)).match() } ) } } @@ -101,22 +170,21 @@ nextflow_workflow { input[1] = CHROMAP_INDEX.out.index input[2] = Channel.of([ [id:'test'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists:true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists:true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists:true) ]) input[3] = [] input[4] = [] input[5] = [] input[6] = [] + input[7] = false """ } } then { assertAll( { assert workflow.success }, - { assert snapshot( - workflow.out, - workflow.out.versions.collect{ path(it).yaml } - ).match() } + { assert snapshot(sanitizeOutput(workflow.out)).match() } ) } } diff --git a/subworkflows/nf-core/fastq_align_chromap/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_align_chromap/tests/main.nf.test.snap index eb247598..37d031ac 100644 --- a/subworkflows/nf-core/fastq_align_chromap/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_align_chromap/tests/main.nf.test.snap @@ -2,88 +2,40 @@ "test_fastq_align_chromap_single_end": { "content": [ { - "0": [ - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,74b5083e3c8ac8f918986fe0b36a9317" - ] - ], - "1": [ - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam.bai:md5,9fcb4c0bf711694916e282e163fba868" - ] - ], - "2": [ - [ - { - "id": "test", - "single_end": true - }, - "test.stats:md5,de59e4f73eee31c4fbe8ec3859c5e0e8" - ] - ], - "3": [ - [ - { - "id": "test", - "single_end": true - }, - "test.flagstat:md5,99698bba57b57c7ab68b32bc368a0cc5" - ] - ], - "4": [ - [ - { - "id": "test", - "single_end": true - }, - "test.idxstats:md5,0ca8c5edb633a2f4c72fb3160cc25abf" - ] - ], - "5": [ - "versions.yml:md5,510f8807b7572d3ba4db55439fc53106" - ], - "bai": [ + "bam": [ [ { "id": "test", "single_end": true }, - "test.sorted.bam.bai:md5,9fcb4c0bf711694916e282e163fba868" + "test.sorted.bam:md5,0dee4a081e53f90c6d039824025b6028" ] ], - "bam": [ + "flagstat": [ [ { "id": "test", "single_end": true }, - "test.sorted.bam:md5,74b5083e3c8ac8f918986fe0b36a9317" + "test.sorted.bam.flagstat:md5,99698bba57b57c7ab68b32bc368a0cc5" ] ], - "flagstat": [ + "idxstats": [ [ { "id": "test", "single_end": true }, - "test.flagstat:md5,99698bba57b57c7ab68b32bc368a0cc5" + "test.sorted.bam.idxstats:md5,0ca8c5edb633a2f4c72fb3160cc25abf" ] ], - "idxstats": [ + "index": [ [ { "id": "test", "single_end": true }, - "test.idxstats:md5,0ca8c5edb633a2f4c72fb3160cc25abf" + "test.sorted.bam.bai:md5,c91870ca4b40436a0e9ceedad8fbed8c" ] ], "stats": [ @@ -92,105 +44,110 @@ "id": "test", "single_end": true }, - "test.stats:md5,de59e4f73eee31c4fbe8ec3859c5e0e8" + "test.sorted.bam.stats:md5,813d8c081cd42fc60c5bda88611e0e6e" ] - ], - "versions": [ - "versions.yml:md5,510f8807b7572d3ba4db55439fc53106" ] } ], + "timestamp": "2026-07-15T10:01:46.149093", "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.3" - }, - "timestamp": "2026-02-03T11:20:25.710632877" + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } }, "test_fastq_align_chromap_paired_end": { "content": [ { - "0": [ + "bam": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam:md5,bd04f77fe97bc452dffaef24bf255829" + "test.sorted.bam:md5,284d65dcd5b5061a924d817109bab514" ] ], - "1": [ + "flagstat": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam.bai:md5,8084ffd06103a6d2cd66c4749d301b5c" + "test.sorted.bam.flagstat:md5,2fa0d90162a1b655863796c2a6bd8f45" ] ], - "2": [ + "idxstats": [ [ { "id": "test", "single_end": false }, - "test.stats:md5,0900a093aaa649986631997b2b4e919d" + "test.sorted.bam.idxstats:md5,1adb27b52d4d64b826f48b59d61dcd4d" ] ], - "3": [ + "index": [ [ { "id": "test", "single_end": false }, - "test.flagstat:md5,2fa0d90162a1b655863796c2a6bd8f45" + "test.sorted.bam.bai:md5,7cccc7484bcab9060221153fb8ab9143" ] ], - "4": [ + "stats": [ [ { "id": "test", "single_end": false }, - "test.idxstats:md5,1adb27b52d4d64b826f48b59d61dcd4d" + "test.sorted.bam.stats:md5,bbe7d1234474cccc926499f7e15744b8" ] - ], - "5": [ - "versions.yml:md5,510f8807b7572d3ba4db55439fc53106" - ], - "bai": [ + ] + } + ], + "timestamp": "2026-07-15T10:01:55.610632", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "test_fastq_align_chromap_paired_end_add_readgroups": { + "content": [ + { + "bam": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam.bai:md5,8084ffd06103a6d2cd66c4749d301b5c" + "test.sorted.bam:md5,658b738d37c813b528371a22193cdb68" ] ], - "bam": [ + "flagstat": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam:md5,bd04f77fe97bc452dffaef24bf255829" + "test.sorted.bam.flagstat:md5,2fa0d90162a1b655863796c2a6bd8f45" ] ], - "flagstat": [ + "idxstats": [ [ { "id": "test", "single_end": false }, - "test.flagstat:md5,2fa0d90162a1b655863796c2a6bd8f45" + "test.sorted.bam.idxstats:md5,1adb27b52d4d64b826f48b59d61dcd4d" ] ], - "idxstats": [ + "index": [ [ { "id": "test", "single_end": false }, - "test.idxstats:md5,1adb27b52d4d64b826f48b59d61dcd4d" + "test.sorted.bam.bai:md5,e1734249192edb61ec95bcddf8a91f2d" ] ], "stats": [ @@ -199,105 +156,110 @@ "id": "test", "single_end": false }, - "test.stats:md5,0900a093aaa649986631997b2b4e919d" + "test.sorted.bam.stats:md5,bbe7d1234474cccc926499f7e15744b8" ] - ], - "versions": [ - "versions.yml:md5,510f8807b7572d3ba4db55439fc53106" ] } ], + "timestamp": "2026-07-15T10:02:36.957514", "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.3" - }, - "timestamp": "2026-02-03T11:20:34.996827974" + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } }, - "test_fastq_align_chromap_paired_end -- stub": { + "test_fastq_align_chromap_single_end_add_readgroups": { "content": [ { - "0": [ + "bam": [ [ { "id": "test", - "single_end": false + "single_end": true }, - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sorted.bam:md5,d6ecb02390b4ce23b16f94c9c875196f" ] ], - "1": [ + "flagstat": [ [ { "id": "test", - "single_end": false + "single_end": true }, - "test.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sorted.bam.flagstat:md5,99698bba57b57c7ab68b32bc368a0cc5" ] ], - "2": [ + "idxstats": [ [ { "id": "test", - "single_end": false + "single_end": true }, - "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sorted.bam.idxstats:md5,0ca8c5edb633a2f4c72fb3160cc25abf" ] ], - "3": [ + "index": [ [ { "id": "test", - "single_end": false + "single_end": true }, - "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" + "test.sorted.bam.bai:md5,6b5aff820e930f71408f7404dc043bff" ] ], - "4": [ + "stats": [ [ { "id": "test", - "single_end": false + "single_end": true }, - "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sorted.bam.stats:md5,813d8c081cd42fc60c5bda88611e0e6e" ] - ], - "5": [ - "versions.yml:md5,510f8807b7572d3ba4db55439fc53106" - ], - "bai": [ + ] + } + ], + "timestamp": "2026-07-15T10:02:15.914993", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "test_fastq_align_chromap_paired_end -- stub": { + "content": [ + { + "bam": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "bam": [ + "flagstat": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sorted.bam.flagstat:md5,67394650dbae96d1a4fcc70484822159" ] ], - "flagstat": [ + "idxstats": [ [ { "id": "test", "single_end": false }, - "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" + "test.sorted.bam.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "idxstats": [ + "index": [ [ { "id": "test", "single_end": false }, - "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "stats": [ @@ -306,26 +268,15 @@ "id": "test", "single_end": false }, - "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sorted.bam.stats:md5,d41d8cd98f00b204e9800998ecf8427e" ] - ], - "versions": [ - "versions.yml:md5,510f8807b7572d3ba4db55439fc53106" ] - }, - [ - { - "FASTQ_ALIGN_CHROMAP:CHROMAP_CHROMAP": { - "chromap": "0.2.6-r490", - "samtools": 1.2 - } - } - ] + } ], + "timestamp": "2026-07-15T10:04:47.695403", "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.3" - }, - "timestamp": "2026-02-03T11:20:43.673771098" + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_align_chromap/tests/nextflow.config b/subworkflows/nf-core/fastq_align_chromap/tests/nextflow.config index 2031964d..dc4082d3 100644 --- a/subworkflows/nf-core/fastq_align_chromap/tests/nextflow.config +++ b/subworkflows/nf-core/fastq_align_chromap/tests/nextflow.config @@ -1,13 +1,18 @@ process { - withName: "CHROMAP_CHROMAP" { + withName: CHROMAP_CHROMAP { ext.args = "--SAM" } - withName: "FASTQ_ALIGN_CHROMAP:BAM_SORT_STATS_SAMTOOLS:SAMTOOLS_.*" { + withName: 'FASTQ_ALIGN_CHROMAP:BAM_SORT_STATS_SAMTOOLS:SAMTOOLS_.*' { ext.prefix = { "${meta.id}.sorted" } } - withName: "FASTQ_ALIGN_CHROMAP:BAM_SORT_STATS_SAMTOOLS:BAM_STATS_SAMTOOLS:.*'" { + withName: 'FASTQ_ALIGN_CHROMAP:PICARD_ADDORREPLACEREADGROUPS*' { + ext.prefix = { "${meta.id}.update_rg" } + ext.args = {"--RGID ${meta.id} --RGSM ${meta.id - ~/_T\d+$/} --RGPL ILLUMINA --RGLB ${meta.id} --RGPU 1 --RGCN nf-core"} + } + + withName: 'FASTQ_ALIGN_CHROMAP:BAM_SORT_STATS_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' { ext.prefix = { "${meta.id}.sorted.bam" } } } diff --git a/tests/.nftignore b/tests/.nftignore index 02868851..74e7f5f3 100644 --- a/tests/.nftignore +++ b/tests/.nftignore @@ -18,6 +18,8 @@ multiqc/multiqc_data/multiqc_sources.txt multiqc/multiqc_plots/{svg,pdf,png}/*.{svg,pdf,png} **/multiqc_data/llms-full.txt **/multiqc_data/multiqc.parquet +**/multiqc/**/multiqc_plots/pdf/* +multiqc/**/multiqc_plots/pdf/ # === QC TOOL OUTPUTS === fastqc/*_fastqc.{html,zip} diff --git a/tests/bowtie2.nf.test.snap b/tests/bowtie2.nf.test.snap index dc0e003f..d1852a1f 100644 --- a/tests/bowtie2.nf.test.snap +++ b/tests/bowtie2.nf.test.snap @@ -91,19 +91,19 @@ "samtools": "1.22.1" }, "SAMTOOLS_FLAGSTAT": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_IDXSTATS": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_INDEX": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_SORT": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_STATS": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SUBREAD_FEATURECOUNTS": { "subread": "2.1.1" @@ -946,7 +946,7 @@ "samplesheet.valid.csv:md5,276425084544b3baf533e2f17207a384" ] ], - "timestamp": "2026-06-20T09:06:05.68183", + "timestamp": "2026-07-15T11:34:27.414025", "meta": { "nf-test": "0.9.5", "nextflow": "26.04.0" @@ -956,10 +956,10 @@ "content": [ 20 ], - "timestamp": "2026-03-14T15:14:30.739354966", + "timestamp": "2026-07-15T11:35:01.664286", "meta": { - "nf-test": "0.9.3", - "nextflow": "25.10.4" + "nf-test": "0.9.5", + "nextflow": "26.04.0" } } } \ No newline at end of file diff --git a/tests/chromap.nf.test.snap b/tests/chromap.nf.test.snap index d4eed2de..996dac69 100644 --- a/tests/chromap.nf.test.snap +++ b/tests/chromap.nf.test.snap @@ -1,7 +1,7 @@ { "chromap": { "content": [ - 215, + 221, { "ANNOTATE_BOOLEAN_PEAKS": { "sed": 4.7 @@ -16,6 +16,10 @@ "BEDTOOLS_GENOMECOV": { "bedtools": "2.31.1" }, + "CHROMAP_CHROMAP": { + "chromap": "0.3.2-r518", + "samtools": "1.23.1" + }, "DEEPTOOLS_COMPUTEMATRIX": { "deeptools": "3.5.6" }, @@ -61,6 +65,9 @@ "MULTIQC_CUSTOM_PHANTOMPEAKQUALTOOLS": { "R": "4.5.3" }, + "PICARD_ADDORREPLACEREADGROUPS": { + "picard": "3.4.0" + }, "PICARD_COLLECTMULTIPLEMETRICS": { "picard": "3.4.0" }, @@ -83,19 +90,19 @@ "samtools": "1.22.1" }, "SAMTOOLS_FLAGSTAT": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_IDXSTATS": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_INDEX": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_SORT": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_STATS": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SUBREAD_FEATURECOUNTS": { "subread": "2.1.1" @@ -399,6 +406,7 @@ "genome/index", "genome/index/chromap", "genome/index/chromap/genome.index", + "genome/index/chromap/versions.yml", "igv", "igv/broad_peak", "igv/broad_peak/igv_files.txt", @@ -809,22 +817,22 @@ "SPT5_T0_REP2.mLb.clN.bedGraph:md5,552f2dc1010cea4e1d822081409bb11b", "SPT5_T15_REP1.mLb.clN.bedGraph:md5,52c8de5177ed6d20c2e598d9d9717de4", "SPT5_T15_REP2.mLb.clN.bedGraph:md5,66db76ce702dea56dd5fb9a8b261a7fb", - "SPT5_T0_REP1_peaks.broadPeak:md5,b4a7e2305ed63853b04d5e18678ea27a", - "SPT5_T0_REP1_peaks.gappedPeak:md5,2765b191811a573296f0122b9a270e4b", - "SPT5_T0_REP1_peaks.xls:md5,c98206fe98326026daf9f76a72de3e5b", - "SPT5_T0_REP2_peaks.broadPeak:md5,62ab089b02bc12cd0031dc86491475f3", - "SPT5_T0_REP2_peaks.gappedPeak:md5,96527d7bc1aec737df63a68f47973ca3", - "SPT5_T0_REP2_peaks.xls:md5,210833a6e5a9d266241408eb05e7e4c5", - "SPT5_T15_REP1_peaks.broadPeak:md5,431281296b82744d3bdd020c97246c33", - "SPT5_T15_REP1_peaks.gappedPeak:md5,2a2721519c702cfa1aeef89cf738ae14", - "SPT5_T15_REP1_peaks.xls:md5,c10e1b3beb4dd8bec17e05dc0e2b21db", - "SPT5_T15_REP2_peaks.broadPeak:md5,b362db9e035e538aae20a6e1d3528129", - "SPT5_T15_REP2_peaks.gappedPeak:md5,7568ce0e0a8ac4cf4dd368b5ad861815", - "SPT5_T15_REP2_peaks.xls:md5,53a6728105f880c08a813adf23e1bbfd", + "SPT5_T0_REP1_peaks.broadPeak:md5,51fa6677a61b5b8bec62dd35039e45ff", + "SPT5_T0_REP1_peaks.gappedPeak:md5,018ababe569ddd6be350622586dc6a2e", + "SPT5_T0_REP1_peaks.xls:md5,f6375b0f1d192c2fc6a768b1a439a5e7", + "SPT5_T0_REP2_peaks.broadPeak:md5,255285fdb4abcb611013cd953cd3c078", + "SPT5_T0_REP2_peaks.gappedPeak:md5,f5e4fee8b3ac7b3aba7068e6d2325fe1", + "SPT5_T0_REP2_peaks.xls:md5,f366ece3bbe73ce1b6a61c1a435613e0", + "SPT5_T15_REP1_peaks.broadPeak:md5,eae77d4812752bca7cadcefc2d97bea5", + "SPT5_T15_REP1_peaks.gappedPeak:md5,3cd002eedcc24dc427a4ec7da3378497", + "SPT5_T15_REP1_peaks.xls:md5,cb7a680b7c70601cf9e4728cbe82eebf", + "SPT5_T15_REP2_peaks.broadPeak:md5,9bbe049391466ec925d4474079aa5295", + "SPT5_T15_REP2_peaks.gappedPeak:md5,d57b0a428c02d6cb4024fe570d7352a7", + "SPT5_T15_REP2_peaks.xls:md5,1234fc1e8040158c3b523491afa4dfc7", "SPT5.consensus_peaks.antibody.txt:md5,8d7549b0cb2e42ffd5c23879e7f54ce9", "SPT5.consensus_peaks.bed:md5,f907ace2725a7640c56659dabdd87325", "SPT5.consensus_peaks.boolean.intersect.txt:md5,ccb9a148841bee735e645ae10a03d5ef", - "SPT5.consensus_peaks.boolean.txt:md5,0aa4347a6eaaf04d407ca3c7cbbe2012", + "SPT5.consensus_peaks.boolean.txt:md5,52450991ebabced23395d253ffd887b5", "SPT5.consensus_peaks.saf:md5,084dbc36235b2e47a7deedb1e252305d", "R_sessionInfo.log:md5,fb0da0d7ad6994ed66a8e68348b19676", "SPT5_T0_REP1.txt:md5,19574031268672407c6470c85d893f8a", @@ -855,6 +863,7 @@ "genome.fa.fai:md5,6f4c0ce5258e6948135ad006e1f9ee1b", "genome.fa.sizes:md5,e122f8021a5ef14104c32785cb9b7adc", "genome.index:md5,377432ea6242989cae4dabb60859f6bd", + "versions.yml:md5,f4e3f5d26dba5b7ed6a0badc6f156d07", "cutadapt_filtered_reads_plot.yaml:md5,976fdb8049d847c977195863418e3655", "cutadapt_trimmed_sequences_plot_3_Counts.yaml:md5,1dba61b1d90518e1f020b71c4cfa04c4", "cutadapt_trimmed_sequences_plot_3_Obs_Exp.yaml:md5,42335c2990d3a991e2bd0716f80b0515", @@ -891,58 +900,58 @@ "multiqc_phantompeakqualtools.yaml:md5,a28abb9241ec87e4a0d077f29acf6669", "multiqc_picard-1_AlignmentSummaryMetrics_picard-1.yaml:md5,73dfc8dfa07e06633c66e12715ab2b18", "multiqc_picard-1_insertSize_picard-1.yaml:md5,3364ad42f23a53723388df3f0b13a25d", - "multiqc_picard-1_quality_by_cycle_picard-1.yaml:md5,c3036e5c3626ca012a7345b3b578ad8f", - "multiqc_picard-1_quality_score_distribution_picard-1.yaml:md5,37ef6ec1ee50f6816b703f3f7d4040c9", - "multiqc_picard_baseContent_picard-1.yaml:md5,39b10e42d8b300d3b6dc2bb8d453c8e8", - "multiqc_picard_dups.yaml:md5,15a0c399e9eb03f96b6986897d28ee46", + "multiqc_picard-1_quality_by_cycle_picard-1.yaml:md5,5b73b22df25b57bafe45d8783d39bced", + "multiqc_picard-1_quality_score_distribution_picard-1.yaml:md5,bebc0cfe83cdb2c5798dead47c7fd020", + "multiqc_picard_baseContent_picard-1.yaml:md5,ca84a08512ec7ffde05cb3d1f7f8fe8f", + "multiqc_picard_dups.yaml:md5,ee75e28c6db880bf1f0c18da0eef9927", "multiqc_rsc_coefficient.yaml:md5,4cdfd1cf61b780606ff79b3b7702e2d3", - "multiqc_samtools_flagstat.yaml:md5,b0602157e3b133c8c6a5ea0da373f95e", - "multiqc_samtools_flagstat_samtools-1.yaml:md5,3d34f85288be603b026182b3153d73b0", + "multiqc_samtools_flagstat.yaml:md5,0f8c8c7fac8466064b5487950d128f38", + "multiqc_samtools_flagstat_samtools-1.yaml:md5,bbfaf4b282f096802f595d348102fc13", "multiqc_samtools_flagstat_samtools-2.yaml:md5,e1ff04aa8821cea5669edc9e158c61f0", - "multiqc_samtools_idxstats.yaml:md5,ea5462b130dba17cc734b06fdffea98f", - "multiqc_samtools_idxstats_samtools-1.yaml:md5,ca00f0c2ad430266007ad46b39950976", + "multiqc_samtools_idxstats.yaml:md5,16bb2bb59fd370f34153fdf7854d3f3b", + "multiqc_samtools_idxstats_samtools-1.yaml:md5,8d3bd1ee7c7c4d3cf1c8da18bb8323a3", "multiqc_samtools_idxstats_samtools-2.yaml:md5,431ef2b34a7c7c9d6123b3ac5f49a9eb", - "multiqc_samtools_stats.yaml:md5,a7808cb87393256d4b1f20d8ffa6d5ef", - "multiqc_samtools_stats_samtools-1.yaml:md5,aaa97e9703d0da10544c3c3f44facff4", - "multiqc_samtools_stats_samtools-2.yaml:md5,84c66e46d40774e0ef59aba7e4d25a2b", + "multiqc_samtools_stats.yaml:md5,18aa457701c5721ee6cc9dd861e1f54b", + "multiqc_samtools_stats_samtools-1.yaml:md5,2fb44c40d15c900f762a926f0100bacf", + "multiqc_samtools_stats_samtools-2.yaml:md5,a2cbc92a8963a77b21fae49bda2f62c1", "picard-1_MarkIlluminaAdapters_histogram_picard-1.yaml:md5,8a80554c91d9fca8acb82f023de02f11", "picard-1_MeanQualityByCycle_histogram_picard-1.yaml:md5,8a80554c91d9fca8acb82f023de02f11", - "picard-1_MeanQualityByCycle_histogram_picard-1_1.yaml:md5,c3036e5c3626ca012a7345b3b578ad8f", - "picard-1_QualityScoreDistribution_histogram_picard-1.yaml:md5,37ef6ec1ee50f6816b703f3f7d4040c9", + "picard-1_MeanQualityByCycle_histogram_picard-1_1.yaml:md5,5b73b22df25b57bafe45d8783d39bced", + "picard-1_QualityScoreDistribution_histogram_picard-1.yaml:md5,bebc0cfe83cdb2c5798dead47c7fd020", "picard-1_alignment_readlength_plot.yaml:md5,654f00b7a14220482e4eab35dda2e2a4", "picard-1_alignment_summary_Aligned_Bases.yaml:md5,890df66d27392114a8fff8b92062f884", "picard-1_alignment_summary_Aligned_Reads.yaml:md5,41a9fd39fa4e4cf4874c74d9c3b1b36f", "picard-1_insert_size_Counts.yaml:md5,1d06f38b9904f9a43999cb3894d60d0b", "picard-1_insert_size_Percentages.yaml:md5,8256d8f2b45d26bea3c011702c449799", - "picard-1_quality_by_cycle.yaml:md5,b119f1649c55b3d660817f236a94a496", - "picard-1_quality_score_distribution.yaml:md5,d38889b5767b074cb69d7efd13d87565", + "picard-1_quality_by_cycle.yaml:md5,4045e529937122b8961ec6af73fc5ae6", + "picard-1_quality_score_distribution.yaml:md5,4eeb45f39924ee62b75137b6d0951011", "picard_MarkIlluminaAdapters_histogram.yaml:md5,8a80554c91d9fca8acb82f023de02f11", "picard_MeanQualityByCycle_histogram.yaml:md5,8a80554c91d9fca8acb82f023de02f11", "picard_MeanQualityByCycle_histogram_1.yaml:md5,8a80554c91d9fca8acb82f023de02f11", "picard_QualityScoreDistribution_histogram.yaml:md5,8a80554c91d9fca8acb82f023de02f11", - "picard_base_distribution_by_cycle__Adenine.yaml:md5,a6d21988c39254c54cc9680820b97537", - "picard_base_distribution_by_cycle__Cytosine.yaml:md5,d1b9ded13f629f8f8392773bcfcc91ec", - "picard_base_distribution_by_cycle__Guanine.yaml:md5,5b703b51b4db9eac363b42bbe6f63c5d", - "picard_base_distribution_by_cycle__Thymine.yaml:md5,594c63ee377428fa414e2c9b90ff5f40", + "picard_base_distribution_by_cycle__Adenine.yaml:md5,4c46716d8cea7bed4ec142ef97d105e5", + "picard_base_distribution_by_cycle__Cytosine.yaml:md5,10b12b93ef03c842c2a3b70453873ceb", + "picard_base_distribution_by_cycle__Guanine.yaml:md5,005523c3d1a79c9d5d98ed15e7a34bbd", + "picard_base_distribution_by_cycle__Thymine.yaml:md5,d845c2eec01eb6bf1dccda0d21251408", "picard_base_distribution_by_cycle__Undetermined.yaml:md5,5fcdc8fd9bdc545986c9340a12723e73", - "picard_deduplication.yaml:md5,7ff4f04ead40ec4e9e5b7ba071848260", + "picard_deduplication.yaml:md5,d3f0a1a13eac808a55d7c152520a4168", "samtools-flagstat-pct-table.yaml:md5,1b1eec5d19ddf1b345b133f2fda62036", "samtools-flagstat-table.yaml:md5,838317f2e7734a94a078523723d32843", - "samtools-idxstats-mapped-reads-plot_Normalised_Counts-1.yaml:md5,8f4fff3963b1ac99cea6d383f8643408", + "samtools-idxstats-mapped-reads-plot_Normalised_Counts-1.yaml:md5,21f2f491ec38ccd273537a22e655ddee", "samtools-idxstats-mapped-reads-plot_Normalised_Counts-2.yaml:md5,4e71bf6886f146683bd0de1ff5f252a9", - "samtools-idxstats-mapped-reads-plot_Normalised_Counts.yaml:md5,28798f61ef786d1121cd60535d8d8a12", - "samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts-1.yaml:md5,f9d9ff9b3a48c80080f06224e369ed16", + "samtools-idxstats-mapped-reads-plot_Normalised_Counts.yaml:md5,224d90875d03967b48da322035ee33d2", + "samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts-1.yaml:md5,99c6590113c6095f3d2aa4843cd0c3a6", "samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts-2.yaml:md5,4e11d304039ec78f557e5cf36447d15a", - "samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts.yaml:md5,2a969645b5bc2b45754706e026d30bc4", - "samtools-idxstats-mapped-reads-plot_Raw_Counts-1.yaml:md5,9c55f8f6fc48ccf9fdc1e056ea880b82", + "samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts.yaml:md5,8f3ecccf389cf65b4de982a8ba34e4e3", + "samtools-idxstats-mapped-reads-plot_Raw_Counts-1.yaml:md5,a4da6c5404d129982377e2086a2247be", "samtools-idxstats-mapped-reads-plot_Raw_Counts-2.yaml:md5,5f6e7048432cec03afda912db5052a12", - "samtools-idxstats-mapped-reads-plot_Raw_Counts.yaml:md5,89fd9a44ab2de47153f4ff077e90b074", + "samtools-idxstats-mapped-reads-plot_Raw_Counts.yaml:md5,341673952bb97bc2cee196c4e37e3a5f", "samtools-stats-dp.yaml:md5,a6bf11b91c4d80c11d84fe7f5cab8cb7", "samtools_alignment_plot.yaml:md5,861b787bfca0dac75cb2d9467ee21f36", "samplesheet.valid.csv:md5,276425084544b3baf533e2f17207a384" ] ], - "timestamp": "2026-06-20T09:16:06.518313", + "timestamp": "2026-07-15T11:45:39.473638", "meta": { "nf-test": "0.9.5", "nextflow": "26.04.0" @@ -952,10 +961,10 @@ "content": [ 20 ], - "timestamp": "2026-03-17T14:23:25.411753", + "timestamp": "2026-07-15T11:46:07.963583", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.04.0" + "nf-test": "0.9.5", + "nextflow": "26.04.0" } } } \ No newline at end of file diff --git a/tests/default.nf.test.snap b/tests/default.nf.test.snap index d14cf61b..dcb933ee 100644 --- a/tests/default.nf.test.snap +++ b/tests/default.nf.test.snap @@ -90,19 +90,19 @@ "samtools": "1.22.1" }, "SAMTOOLS_FLAGSTAT": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_IDXSTATS": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_INDEX": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_SORT": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_STATS": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SUBREAD_FEATURECOUNTS": { "subread": "2.1.1" @@ -945,7 +945,7 @@ "samplesheet.valid.csv:md5,276425084544b3baf533e2f17207a384" ] ], - "timestamp": "2026-06-20T09:26:27.903591", + "timestamp": "2026-07-15T11:55:46.742037", "meta": { "nf-test": "0.9.5", "nextflow": "26.04.0" diff --git a/tests/skip_consensus_peaks.nf.test.snap b/tests/skip_consensus_peaks.nf.test.snap index 5407db11..368c77b1 100644 --- a/tests/skip_consensus_peaks.nf.test.snap +++ b/tests/skip_consensus_peaks.nf.test.snap @@ -3,10 +3,10 @@ "content": [ 20 ], - "timestamp": "2026-03-17T14:29:41.990841", + "timestamp": "2026-07-15T12:05:47.280876", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.04.0" + "nf-test": "0.9.5", + "nextflow": "26.04.0" } }, "skip_consensus_peaks": { @@ -89,19 +89,19 @@ "samtools": "1.22.1" }, "SAMTOOLS_FLAGSTAT": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_IDXSTATS": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_INDEX": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_SORT": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_STATS": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "TRIMGALORE": { "trimgalore": "0.6.10" @@ -886,7 +886,7 @@ "samplesheet.valid.csv:md5,276425084544b3baf533e2f17207a384" ] ], - "timestamp": "2026-06-20T09:35:30.906145", + "timestamp": "2026-07-15T12:05:20.927401", "meta": { "nf-test": "0.9.5", "nextflow": "26.04.0" diff --git a/tests/skip_trimming.nf.test.snap b/tests/skip_trimming.nf.test.snap index 4405a0c8..af3f6bce 100644 --- a/tests/skip_trimming.nf.test.snap +++ b/tests/skip_trimming.nf.test.snap @@ -90,19 +90,19 @@ "samtools": "1.22.1" }, "SAMTOOLS_FLAGSTAT": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_IDXSTATS": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_INDEX": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_SORT": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_STATS": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SUBREAD_FEATURECOUNTS": { "subread": "2.1.1" @@ -823,7 +823,7 @@ "samplesheet.valid.csv:md5,276425084544b3baf533e2f17207a384" ] ], - "timestamp": "2026-06-20T09:44:50.992423", + "timestamp": "2026-07-15T12:14:38.105873", "meta": { "nf-test": "0.9.5", "nextflow": "26.04.0" @@ -833,10 +833,10 @@ "content": [ 190 ], - "timestamp": "2026-03-17T14:36:41.411257", + "timestamp": "2026-07-15T12:18:14.397449", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.04.0" + "nf-test": "0.9.5", + "nextflow": "26.04.0" } } } \ No newline at end of file diff --git a/tests/star.nf.test.snap b/tests/star.nf.test.snap index 2003110e..4ccb35ff 100644 --- a/tests/star.nf.test.snap +++ b/tests/star.nf.test.snap @@ -83,19 +83,19 @@ "samtools": "1.22.1" }, "SAMTOOLS_FLAGSTAT": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_IDXSTATS": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_INDEX": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_SORT": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "SAMTOOLS_STATS": { - "samtools": "1.22.1" + "samtools": "1.23.1" }, "STAR_ALIGN": { "star": "2.7.11b" @@ -977,7 +977,7 @@ "SPT5_T15_REP2.mLb.clN.sorted.bam.idxstats:md5,aa2db2bcb3aa876cfbfe24b49d98aabd" ] ], - "timestamp": "2026-06-20T09:59:04.660863", + "timestamp": "2026-07-15T12:28:14.404035", "meta": { "nf-test": "0.9.5", "nextflow": "26.04.0" @@ -987,10 +987,10 @@ "content": [ 20 ], - "timestamp": "2026-03-17T16:23:46.465421", + "timestamp": "2026-07-15T12:28:44.226288", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.04.0" + "nf-test": "0.9.5", + "nextflow": "26.04.0" } } } \ No newline at end of file diff --git a/workflows/chipseq.nf b/workflows/chipseq.nf index bd78381b..c2fbf548 100644 --- a/workflows/chipseq.nf +++ b/workflows/chipseq.nf @@ -151,25 +151,29 @@ workflow CHIPSEQ { ) // - // SUBWORKFLOW: Alignment with BWA & BAM QC + // Initialize common channels // ch_genome_bam = channel.empty() ch_genome_bam_index = channel.empty() ch_samtools_stats = channel.empty() ch_samtools_flagstat = channel.empty() ch_samtools_idxstats = channel.empty() + + // + // SUBWORKFLOW: Alignment with BWA & BAM QC + // if (params.aligner == 'bwa') { FASTQ_ALIGN_BWA ( FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.reads, ch_bwa_index, false, ch_fasta - .map { - [ [:], it ] + .map { fasta -> + [ [:], fasta, [] ] } ) ch_genome_bam = FASTQ_ALIGN_BWA.out.bam - ch_genome_bam_index = FASTQ_ALIGN_BWA.out.bai + ch_genome_bam_index = FASTQ_ALIGN_BWA.out.index ch_samtools_stats = FASTQ_ALIGN_BWA.out.stats ch_samtools_flagstat = FASTQ_ALIGN_BWA.out.flagstat ch_samtools_idxstats = FASTQ_ALIGN_BWA.out.idxstats @@ -185,12 +189,12 @@ workflow CHIPSEQ { params.save_unaligned, false, ch_fasta - .map { - [ [:], it ] + .map { fasta -> + [ [:], fasta, [] ] } ) ch_genome_bam = FASTQ_ALIGN_BOWTIE2.out.bam - ch_genome_bam_index = FASTQ_ALIGN_BOWTIE2.out.bai + ch_genome_bam_index = FASTQ_ALIGN_BOWTIE2.out.index ch_samtools_stats = FASTQ_ALIGN_BOWTIE2.out.stats ch_samtools_flagstat = FASTQ_ALIGN_BOWTIE2.out.flagstat ch_samtools_idxstats = FASTQ_ALIGN_BOWTIE2.out.idxstats @@ -204,16 +208,17 @@ workflow CHIPSEQ { FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.reads, ch_chromap_index, ch_fasta - .map { - [ [:], it ] + .map { fasta -> + [ [:], fasta, [] ] }, [], [], [], - [] + [], + true ) ch_genome_bam = FASTQ_ALIGN_CHROMAP.out.bam - ch_genome_bam_index = FASTQ_ALIGN_CHROMAP.out.bai + ch_genome_bam_index = FASTQ_ALIGN_CHROMAP.out.index ch_samtools_stats = FASTQ_ALIGN_CHROMAP.out.stats ch_samtools_flagstat = FASTQ_ALIGN_CHROMAP.out.flagstat ch_samtools_idxstats = FASTQ_ALIGN_CHROMAP.out.idxstats @@ -223,14 +228,15 @@ workflow CHIPSEQ { // SUBWORKFLOW: Alignment with STAR & BAM QC // if (params.aligner == 'star') { + def seq_center = params.seq_center ?: '' ALIGN_STAR ( FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.reads, ch_star_index, ch_fasta - .map { - [ [:], it ] + .map { fasta -> + [ [:], fasta, [] ] }, - params.seq_center ?: '' + seq_center ) ch_genome_bam = ALIGN_STAR.out.bam ch_genome_bam_index = ALIGN_STAR.out.bai @@ -266,27 +272,23 @@ workflow CHIPSEQ { // // SUBWORKFLOW: Mark duplicates & filter BAM files after merging // + ch_fasta_fai = ch_fasta.combine(ch_fai) + .map {fasta, fai -> [ [:], fasta, fai]} + BAM_MARKDUPLICATES_PICARD ( PICARD_MERGESAMFILES.out.bam, - ch_fasta - .map { - [ [:], it ] - }, - ch_fai - .map { - [ [:], it ] - } + ch_fasta_fai.first() ) // // SUBWORKFLOW: Filter BAM file with BamTools // BAM_FILTER_BAMTOOLS ( - BAM_MARKDUPLICATES_PICARD.out.bam.join(BAM_MARKDUPLICATES_PICARD.out.bai, by: [0]), + BAM_MARKDUPLICATES_PICARD.out.bam.join(BAM_MARKDUPLICATES_PICARD.out.index, by: [0]), ch_filtered_bed.first(), ch_fasta - .map { - [ [:], it ] + .map { fasta -> + [ [:], fasta ] }, ch_bamtools_filter_se_config, ch_bamtools_filter_pe_config