diff --git a/subworkflows/nf-core/fastq_align_chromap/main.nf b/subworkflows/nf-core/fastq_align_chromap/main.nf index f627a0f37ac6..c80fd5e8ba8a 100644 --- a/subworkflows/nf-core/fastq_align_chromap/main.nf +++ b/subworkflows/nf-core/fastq_align_chromap/main.nf @@ -2,8 +2,9 @@ * 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: @@ -14,9 +15,13 @@ workflow FASTQ_ALIGN_CHROMAP { 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_bam = channel.empty() + def add_readgroups = update_readgroups ?: false + // // Remap ch_fasta_fai to ch_fasta // @@ -27,10 +32,21 @@ workflow FASTQ_ALIGN_CHROMAP { // CHROMAP_CHROMAP(ch_reads, ch_fasta, ch_index, ch_barcodes, ch_whitelist, ch_chr_order, ch_pairs_chr_order) + // + // Update read groups + // + PICARD_ADDORREPLACEREADGROUPS(CHROMAP_CHROMAP.out.bam, ch_fasta_fai) + + if (add_readgroups == true) { + 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_fai) + BAM_SORT_STATS_SAMTOOLS(ch_bam, ch_fasta_fai) emit: bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), [ bam ] ] diff --git a/subworkflows/nf-core/fastq_align_chromap/meta.yml b/subworkflows/nf-core/fastq_align_chromap/meta.yml index f0a9921faa7a..f433cabba49b 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 @@ -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 467f238ef881..41b2209cf9f9 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" @@ -46,16 +47,18 @@ nextflow_workflow { 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 { @@ -77,13 +80,77 @@ nextflow_workflow { input[4] = [] input[5] = [] input[6] = [] + input[7] = false + """ + } + } + then { + assertAll( + { assert workflow.success }, + { 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(workflow.out).match() } + { assert snapshot(sanitizeOutput(workflow.out)).match() } ) } } @@ -110,13 +177,14 @@ nextflow_workflow { 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() } ) } } 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 9220d042c037..c04a8509b114 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,51 +2,6 @@ "test_fastq_align_chromap_single_end": { "content": [ { - "0": [ - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam:md5,3ea7d664a0a0c9f9bd8a2b000d2374c1" - ] - ], - "1": [ - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam.bai:md5,7d430ef50fcff34620d96d3c31797d27" - ] - ], - "2": [ - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam.stats:md5,746dde58f858b3a504886f3c294f201a" - ] - ], - "3": [ - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam.flagstat:md5,99698bba57b57c7ab68b32bc368a0cc5" - ] - ], - "4": [ - [ - { - "id": "test", - "single_end": true - }, - "test.sorted.bam.idxstats:md5,0ca8c5edb633a2f4c72fb3160cc25abf" - ] - ], "bam": [ [ { @@ -94,16 +49,16 @@ ] } ], - "timestamp": "2026-04-01T22:05:11.84639", + "timestamp": "2026-07-08T09:34:04.603515", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.10.4" + "nf-test": "0.9.5", + "nextflow": "26.04.0" } }, "test_fastq_align_chromap_paired_end": { "content": [ { - "0": [ + "bam": [ [ { "id": "test", @@ -112,49 +67,60 @@ "test.sorted.bam:md5,852ba39ffed911e1b713f4ff9040e0c1" ] ], - "1": [ + "flagstat": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam.bai:md5,31f5969b2c5cd2056c87fd566353239b" + "test.sorted.bam.flagstat:md5,2fa0d90162a1b655863796c2a6bd8f45" ] ], - "2": [ + "idxstats": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam.stats:md5,e7187e959c98eca8018ccef10b1d08ad" + "test.sorted.bam.idxstats:md5,1adb27b52d4d64b826f48b59d61dcd4d" ] ], - "3": [ + "index": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam.flagstat:md5,2fa0d90162a1b655863796c2a6bd8f45" + "test.sorted.bam.bai:md5,31f5969b2c5cd2056c87fd566353239b" ] ], - "4": [ + "stats": [ [ { "id": "test", "single_end": false }, - "test.sorted.bam.idxstats:md5,1adb27b52d4d64b826f48b59d61dcd4d" + "test.sorted.bam.stats:md5,e7187e959c98eca8018ccef10b1d08ad" ] - ], + ] + } + ], + "timestamp": "2026-07-08T09:34:24.796072", + "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:md5,852ba39ffed911e1b713f4ff9040e0c1" + "test.sorted.bam:md5,f92c0d766901bedc759b0f3948705217" ] ], "flagstat": [ @@ -181,7 +147,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam.bai:md5,31f5969b2c5cd2056c87fd566353239b" + "test.sorted.bam.bai:md5,e6411d7d79fce192d7d52172eab5e619" ] ], "stats": [ @@ -195,60 +161,71 @@ ] } ], - "timestamp": "2026-04-01T22:05:26.399485", + "timestamp": "2026-07-08T09:35:10.249622", "meta": { - "nf-test": "0.9.4", - "nextflow": "25.10.4" + "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,3f4e5c599d3320be1f1e3ec201f3ea8f" ] ], - "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.sorted.bam.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sorted.bam.idxstats:md5,0ca8c5edb633a2f4c72fb3160cc25abf" ] ], - "3": [ + "index": [ [ { "id": "test", - "single_end": false + "single_end": true }, - "test.sorted.bam.flagstat:md5,67394650dbae96d1a4fcc70484822159" + "test.sorted.bam.bai:md5,c02dbd04a3f15a023e74e12487aeb74d" ] ], - "4": [ + "stats": [ [ { "id": "test", - "single_end": false + "single_end": true }, - "test.sorted.bam.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sorted.bam.stats:md5,746dde58f858b3a504886f3c294f201a" ] - ], + ] + } + ], + "timestamp": "2026-07-08T09:34:46.755736", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + }, + "test_fastq_align_chromap_paired_end -- stub": { + "content": [ + { "bam": [ [ { @@ -296,10 +273,10 @@ ] } ], - "timestamp": "2026-04-01T22:05:39.99444", + "timestamp": "2026-07-08T09:35:29.810372", "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/subworkflows/nf-core/fastq_align_chromap/tests/nextflow.config b/subworkflows/nf-core/fastq_align_chromap/tests/nextflow.config index e890a80ec51a..850452db30fa 100644 --- a/subworkflows/nf-core/fastq_align_chromap/tests/nextflow.config +++ b/subworkflows/nf-core/fastq_align_chromap/tests/nextflow.config @@ -6,6 +6,10 @@ process { withName: 'FASTQ_ALIGN_CHROMAP:BAM_SORT_STATS_SAMTOOLS:SAMTOOLS_.*' { ext.prefix = { "${meta.id}.sorted" } } + 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" }