Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions subworkflows/nf-core/ubam_align_minimap2/main.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//
// Optionally concatenate uBAM files, align with minimap2, index BAM, and run BAM stats.
//

include { SAMTOOLS_CAT } from '../../../modules/nf-core/samtools/cat/main'
include { MINIMAP2_ALIGN } from '../../../modules/nf-core/minimap2/align/main'
include { BAM_STATS_SAMTOOLS } from '../bam_stats_samtools/main'

workflow UBAM_ALIGN_MINIMAP2 {

take:
ch_ubam
// [ val(meta), path(ubam) ]
// ubam may be one BAM/uBAM file or a list of BAM/uBAM files.

ch_fasta_fai
// [ val(meta2), path(fasta), path(fai) ]

val_bam_index_extension
// "bai" or "csi"

val_cigar_bam
// true/false

val_skip_cat
// true: pass one uBAM directly to minimap2
// false: concatenate uBAM files with samtools/cat before minimap2

main:

ch_fasta = ch_fasta_fai.map { meta, fasta, _fai -> [ meta, fasta ] }

ch_cat_ubam = channel.empty()

if (val_skip_cat) {
ch_ubam_for_alignment = ch_ubam
} else {
SAMTOOLS_CAT(ch_ubam)
ch_ubam_for_alignment = SAMTOOLS_CAT.out.bam
ch_cat_ubam = SAMTOOLS_CAT.out.bam
}

MINIMAP2_ALIGN(
ch_ubam_for_alignment,
ch_fasta,
true,
val_bam_index_extension,
false,
val_cigar_bam
)

MINIMAP2_ALIGN.out.bam
.join(MINIMAP2_ALIGN.out.index, by: 0, failOnDuplicate: true, failOnMismatch: true)
.set { ch_bam_bai }

BAM_STATS_SAMTOOLS(ch_bam_bai, ch_fasta_fai)

emit:
ubam = ch_cat_ubam
bam = MINIMAP2_ALIGN.out.bam
index = MINIMAP2_ALIGN.out.index
stats = BAM_STATS_SAMTOOLS.out.stats
flagstat = BAM_STATS_SAMTOOLS.out.flagstat
idxstats = BAM_STATS_SAMTOOLS.out.idxstats
}
67 changes: 67 additions & 0 deletions subworkflows/nf-core/ubam_align_minimap2/meta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json
name: ubam_align_minimap2
description: Optionally concatenate unaligned BAM files, align reads with minimap2, and run BAM statistics
keywords:
- ubam
- bam
- align
- minimap2
- long-read
components:
- samtools/cat
- minimap2/align
- bam_stats_samtools
- samtools/stats
- samtools/flagstat
- samtools/idxstats
input:
- ch_ubam:
description: |
Unaligned BAM input channel.
Structure: [ val(meta), path(ubam) ]
ubam may be one BAM/uBAM file or a list of BAM/uBAM files.
Input files should use the .bam extension.
- ch_fasta_fai:
description: |
Reference FASTA and FASTA index.
Structure: [ val(meta2), path(fasta), path(fai) ]
- val_bam_index_extension:
description: |
BAM index extension created by minimap2/align
Typical values are "bai" or "csi".
- val_cigar_bam:
description: |
Whether to use minimap2 long-CIGAR BAM handling
- val_skip_cat:
description: |
If true, pass one uBAM directly to minimap2.
If false, concatenate uBAM files with samtools/cat before alignment
output:
- ubam:
description: |
Concatenated uBAM file, emitted only when val_skip_cat is false
Structure: [ val(meta), path(bam) ]
- bam:
description: |
Coordinate-sorted BAM file from minimap2
Structure: [ val(meta), path(bam) ]
- index:
description: |
BAM index file.
Structure: [ val(meta), path(index) ]
- stats:
description: |
Samtools stats output from bam_stats_samtools
Structure: [ val(meta), path(stats) ]
- flagstat:
description: |
Samtools flagstat output from bam_stats_samtools
Structure: [ val(meta), path(flagstat) ]
- idxstats:
description: |
Samtools idxstats output from bam_stats_samtools
Structure: [ val(meta), path(idxstats) ]
authors:
- "@manascripts"
maintainers:
- "@manascripts"
154 changes: 154 additions & 0 deletions subworkflows/nf-core/ubam_align_minimap2/tests/main.nf.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
nextflow_workflow {

name "Test Workflow UBAM_ALIGN_MINIMAP2"
script "../main.nf"
workflow "UBAM_ALIGN_MINIMAP2"
config "./nextflow.config"

tag "subworkflows"
tag "subworkflows_nfcore"
tag "subworkflows/ubam_align_minimap2"
tag "samtools/cat"
tag "samtools/import"
tag "minimap2/align"
tag "subworkflows/bam_stats_samtools"

setup {
run("SAMTOOLS_IMPORT", alias: "SAMTOOLS_IMPORT_SINGLE") {
script "../../../../modules/nf-core/samtools/import/main.nf"
process {
"""
input[0] = [
[ id:'test', single_end:true ],
file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists:true)
]
"""
}
}

run("SAMTOOLS_IMPORT", alias: "SAMTOOLS_IMPORT_ONE") {
script "../../../../modules/nf-core/samtools/import/main.nf"
process {
"""
input[0] = [
[ id:'test', single_end:true ],
file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists:true)
]
"""
}
}

run("SAMTOOLS_IMPORT", alias: "SAMTOOLS_IMPORT_TWO") {
script "../../../../modules/nf-core/samtools/import/main.nf"
process {
"""
input[0] = [
[ id:'test', single_end:true ],
file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test_2.fastq.gz', checkIfExists:true)
]
"""
}
}
}

test("nanopore ubam without concatenation") {
when {
workflow {
"""
input[0] = SAMTOOLS_IMPORT_SINGLE.out.bam

input[1] = Channel.value([
[ id:'sarscov2' ],
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'
input[3] = true
input[4] = true
"""
}
}

then {
assertAll(
{ assert workflow.success },
{ assert file(workflow.out.bam[0][1]).exists() },
{ assert file(workflow.out.index[0][1]).exists() },
{ assert snapshot(
workflow.out.stats,
workflow.out.flagstat,
workflow.out.idxstats
).match() }
)
}
}

test("nanopore ubams with concatenation") {
when {
workflow {
"""
input[0] = SAMTOOLS_IMPORT_ONE.out.bam
.join(SAMTOOLS_IMPORT_TWO.out.bam, by: 0, failOnDuplicate: true, failOnMismatch: true)
.map { meta, ubam_one, ubam_two -> [ meta, [ ubam_one, ubam_two ] ] }

input[1] = Channel.value([
[ id:'sarscov2' ],
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'
input[3] = true
input[4] = false
"""
}
}

then {
assertAll(
{ assert workflow.success },
{ assert file(workflow.out.ubam[0][1]).exists() },
{ assert file(workflow.out.bam[0][1]).exists() },
{ assert file(workflow.out.index[0][1]).exists() },
{ assert snapshot(
workflow.out.stats,
workflow.out.flagstat,
workflow.out.idxstats
).match() }
)
}
}

test("nanopore ubam without concatenation - stub") {
options "-stub"

when {
workflow {
"""
input[0] = Channel.of([
[ id:'test', single_end:true ],
file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.sorted.bam', checkIfExists:true)
])

input[1] = Channel.value([
[ id:'sarscov2' ],
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'
input[3] = true
input[4] = true
"""
}
}

then {
assertAll(
{ assert workflow.success },
{ assert snapshot(workflow.out).match() }
)
}
}
}
Loading