Skip to content
Open
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
19162fa
Add coverm/contig to nf-core/modules
vinisalazar Aug 11, 2025
01a8842
Add coverm_mapper parameter for contig coverage estimation
vinisalazar Mar 12, 2026
c3dcf30
Replace jgisummarizebamcontigdepths with COVERM_CONTIG for depths
vinisalazar Mar 12, 2026
2b00d67
Configure COVERM_CONTIG processes in modules.config
vinisalazar Mar 12, 2026
3b9c055
Handle plain-text (non-gzipped) depth files from CoverM
vinisalazar Mar 12, 2026
9d94ae7
Update nf-test snapshots for COVERM_CONTIG process names
vinisalazar Mar 12, 2026
43d3d4d
Add depth_calculator and coverm_methods parameters
vinisalazar Mar 12, 2026
d67af3e
Sync coverm/contig to nf-core modules
vinisalazar Mar 12, 2026
d029395
Sync coverm/contig module and update binning subworkflow
vinisalazar Mar 12, 2026
04de852
CHANGELOG: fix conflict
vinisalazar Mar 16, 2026
e4fa214
docs: update usage.md and output.md
vinisalazar Mar 12, 2026
ec84e7c
CITATIONS.md: add coverm
vinisalazar Mar 12, 2026
c7e509f
README.md: add coverm
vinisalazar Mar 12, 2026
eb5ab55
coverm/contig: update test snapshot
vinisalazar Mar 16, 2026
c8f2649
coverm/contig: update module
vinisalazar Mar 16, 2026
d66a3bb
Update coverm version in test snapshots
vinisalazar Mar 17, 2026
e5b6fa2
rename: coverm_mapper param → coverage_mapper
vinisalazar Mar 24, 2026
ef4c568
feat: drop JGISUMMARIZEBAMCONTIGDEPTHS and depth_calculator param
vinisalazar Mar 24, 2026
a035fe7
feat: repurpose percentidentity params for CoverM --min-read-percent-…
vinisalazar Mar 24, 2026
e8d772b
feat: add --bam-file-cache-directory to CoverM native mapper config
vinisalazar Mar 24, 2026
5e15194
docs: update coverage estimation section in usage.md
vinisalazar Mar 24, 2026
ef5ea46
docs: add CoverM to pipeline summary in ro-crate metadata
vinisalazar Mar 24, 2026
9be9ef9
Merge branch 'dev' into dev
jfy133 Mar 29, 2026
db3115d
Merge remote-tracking branch 'upstream/dev' into dev_vinisalazar
dialvarezs Mar 29, 2026
84433f1
chore: fix snapshots
dialvarezs Mar 29, 2026
1204998
chore: update snapshots
dialvarezs Mar 29, 2026
0d24176
Merge remote-tracking branch 'upstream/dev' into dev_vinisalazar
dialvarezs Apr 6, 2026
0cb9dd3
chore: update snapshots
dialvarezs Apr 6, 2026
8eae4ef
Merge remote-tracking branch 'upstream/dev' into dev_vinisalazar
dialvarezs Apr 9, 2026
6b76b0a
chore: update snapshots
dialvarezs Apr 9, 2026
68b2e38
chore: fix changelog
dialvarezs Apr 9, 2026
eedf198
coverm/contig: update module following nf-core/modules#11111
vinisalazar Apr 14, 2026
9710895
Move CoverM coverage into binning preparation
vinisalazar Apr 14, 2026
0c0f0a4
Update coverage mapper documentation
vinisalazar Apr 14, 2026
5918f33
Add CoverM short-read pipeline test
vinisalazar Apr 14, 2026
2fb2e93
Update ro-crate-metadata.json
vinisalazar Apr 14, 2026
deea255
.nftignore: accept any extensions for depth files
vinisalazar Apr 14, 2026
a0ef5f2
Remove depth files from snapshot
vinisalazar Apr 14, 2026
8a0cb7e
Snapshot versions in CoverM short-read test
vinisalazar Apr 14, 2026
0ff7e5f
Ignore depth files in snapshot
vinisalazar Apr 14, 2026
616918e
Apply suggestions from code review
jfy133 Apr 15, 2026
820bdce
Merge remote-tracking branch 'upstream/dev' into dev_vinisalazar
dialvarezs Apr 15, 2026
9374d1c
chore: update snapshots
dialvarezs Apr 15, 2026
fdef711
Merge branch 'dev' into dev
vinisalazar Apr 23, 2026
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### `Added`

- [#997](https://github.com/nf-core/mag/pull/997) - Add CoverM as the default contig depth/coverage calculator, replacing `jgi_summarize_bam_contig_depths` from MetaBAT2. New parameters added: `--depth_calculator` (default: `coverm`), `--coverm_mapper` (default: `bowtie2`), and `--coverm_methods` (default: `metabat`) (by @vinisalazar)

### `Changed`

- [#1011](https://github.com/nf-core/mag/pull/1011) - Reverted CheckM2 database download workaround from #966 (by @dialvarezs)
Expand All @@ -21,6 +23,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### `Dependencies`

| Tool | Previous version | New version |
| ------ | ---------------- | ----------- |
| CoverM | | 0.7.0 |

### `Deprecated`

- [#1018](https://github.com/nf-core/mag/pull/1018) - Remove `mag_depths_plot` local module (by @dialvarezs)
Expand Down
4 changes: 4 additions & 0 deletions CITATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@

> De Coster W, D'Hert S, Schultz DT, Cruts M, Van Broeckhoven C. NanoPack: visualizing and processing long-read sequencing data. Bioinformatics. 2018 Aug 1;34(15):2666-2669. doi: 10.1093/bioinformatics/bty149

- [CoverM](https://doi.org/10.1093/bioinformatics/btaf147)

> Aroney, S. T. N., Newell, R. J. P., Nissen, J. N., Camargo, A. P., Tyson, G. W., & Woodcroft, B. J. (2025). CoverM: read alignment statistics for metagenomics. Bioinformatics, 41(4), btaf147. doi: 10.1093/bioinformatics/btaf147

- [COMEBin](https://doi.org/10.1038/s41467-023-44290-z)

> Wang Z, You R, Han H, Liu W, Sun F, Zhu S. Effective binning of metagenomic contigs using contrastive multi-view representation learning. Nat Commun. 2024 Jan 17;15(1):585. doi: 10.1038/s41467-023-44290-z. PMID: 38233391; PMCID: PMC10794208.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ The pipeline then:
- performs assembly using [MEGAHIT](https://github.com/voutcn/megahit) and [SPAdes](http://cab.spbu.ru/software/spades/), and checks their quality using [Quast](http://quast.sourceforge.net/quast) and [ALE](https://github.com/sc932/ALE) (if short read data is used)
- (optionally) performs ancient DNA assembly validation using [PyDamage](https://github.com/maxibor/pydamage) and contig consensus sequence recalling with [Freebayes](https://github.com/freebayes/freebayes) and [BCFtools](http://samtools.github.io/bcftools/bcftools.html)
- predicts protein-coding genes for the assemblies using [Prodigal](https://github.com/hyattpd/Prodigal), and bins with [Prokka](https://github.com/tseemann/prokka) and optionally [MetaEuk](https://www.google.com/search?channel=fs&client=ubuntu-sn&q=MetaEuk)
- performs metagenome binning using [MetaBAT2](https://bitbucket.org/berkeleylab/metabat/src/master/), [MaxBin2](https://sourceforge.net/projects/maxbin2/), [CONCOCT](https://github.com/BinPro/CONCOCT), [COMEBin](https://github.com/ziyewang/COMEBin), [MetaBinner](https://github.com/ziyewang/MetaBinner), and/or [SemiBin2](https://github.com/BigDataBiology/SemiBin)
- estimates contig coverage using [CoverM](https://github.com/wwood/CoverM) and performs metagenome binning using [MetaBAT2](https://bitbucket.org/berkeleylab/metabat/src/master/), [MaxBin2](https://sourceforge.net/projects/maxbin2/), [CONCOCT](https://github.com/BinPro/CONCOCT), [COMEBin](https://github.com/ziyewang/COMEBin), [MetaBinner](https://github.com/ziyewang/MetaBinner), and/or [SemiBin2](https://github.com/BigDataBiology/SemiBin)
- checks the quality of the genome bins using [Busco](https://busco.ezlab.org/), [CheckM](https://ecogenomics.github.io/CheckM/), or [CheckM2](https://github.com/chklovski/CheckM2) and optionally [GUNC](https://grp-bork.embl-community.io/gunc/)
- Performs ancient DNA validation and repair with [pyDamage](https://github.com/maxibor/pydamage) and [freebayes](https://github.com/freebayes/freebayes)
- optionally refines bins with [DAS Tool](https://github.com/cmks/DAS_Tool)
Expand Down
3 changes: 2 additions & 1 deletion bin/get_mag_depths.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ def main(args=None):
# load contig depths for all samples into dict (could use pandas as well)
sample_names = []
dict_contig_depths = {}
with gzip.open(args.depths, "rt") as infile:
opener = gzip.open if args.depths.endswith('.gz') else open
with opener(args.depths, "rt") as infile:
reader = csv.DictReader(infile, delimiter="\t")
# process header to extract sample names from column names
depth_columns = []
Expand Down
86 changes: 58 additions & 28 deletions conf/modules.config
Original file line number Diff line number Diff line change
Expand Up @@ -340,25 +340,6 @@ process {
]
}

withName: MINIMAP2_ASSEMBLY_ALIGN {
ext.args = {
meta.lr_platform == "OXFORD_NANOPORE"
? "-x map-ont"
: meta.lr_platform == "OXFORD_NANOPORE_HQ"
? "-x lr:hq"
: meta.lr_platform == "PACBIO_CLR"
? "-x map-pb"
: meta.lr_platform == "PACBIO_HIFI" ? "-x map-hifi" : ""
}
ext.prefix = { "${meta.assembler}-${meta.id}-${meta2.id}" }
publishDir = [
path: { "${params.outdir}/Assembly/${meta2.assembler}/QC/${meta2.id}" },
mode: params.publish_dir_mode,
pattern: "*.{bam,bai}",
enabled: params.save_assembly_mapped_reads,
]
}

withName: SAMTOOLS_HOSTREMOVED_UNMAPPED {
ext.args = '-f 4'
ext.prefix = { "${meta.id}_${meta.run}_hostremoved" }
Expand Down Expand Up @@ -808,23 +789,72 @@ process {
]
}

withName: METABAT2_JGISUMMARIZEBAMCONTIGDEPTHS_SHORTREAD {
withName: 'COVERM_CONTIG_SHORTREAD' {
ext.prefix = { "${meta.assembler}-${meta.id}-depth" }
ext.args = params.shortread_percentidentity ? "--percentIdentity ${params.shortread_percentidentity}" : ''
ext.args = [
'--methods metabat',
params.shortread_coverage_mapper != 'bowtie2' ? "--mapper ${params.shortread_coverage_mapper}" : '',
params.shortread_percentidentity ? "--min-read-percent-identity ${params.shortread_percentidentity}" : '',
].join(' ').trim()
publishDir = [
path: { "${params.outdir}/GenomeBinning/depths/contigs" },
mode: params.publish_dir_mode,
pattern: '*-depth.txt.gz',
[
path: { "${params.outdir}/GenomeBinning/depths/contigs" },
mode: params.publish_dir_mode,
pattern: '*.depth.tsv',
],
[
path: { "${params.outdir}/Assembly/${meta.assembler}/QC/${meta.id}" },
mode: params.publish_dir_mode,
pattern: "*.bam",
enabled: params.save_assembly_mapped_reads,
],
]
}

withName: METABAT2_JGISUMMARIZEBAMCONTIGDEPTHS_LONGREAD {
withName: 'COVERM_CONTIG_LONGREAD' {
ext.prefix = { "${meta.assembler}-${meta.id}-depth" }
ext.args = params.longread_percentidentity ? "--percentIdentity ${params.longread_percentidentity}" : ''
ext.args = {
def mapper = meta.lr_platform in ['OXFORD_NANOPORE', 'OXFORD_NANOPORE_HQ']
? 'minimap2-ont'
: meta.lr_platform == 'PACBIO_CLR'
? 'minimap2-pb'
: meta.lr_platform == 'PACBIO_HIFI' ? 'minimap2-hifi' : ''
[
'--methods metabat',
mapper ? "--mapper ${mapper}" : '',
params.longread_percentidentity ? "--min-read-percent-identity ${params.longread_percentidentity}" : '',
].join(' ').trim()
}
publishDir = [
[
path: { "${params.outdir}/GenomeBinning/depths/contigs" },
mode: params.publish_dir_mode,
pattern: '*.depth.tsv',
],
[
path: { "${params.outdir}/Assembly/${meta.assembler}/QC/${meta.id}" },
mode: params.publish_dir_mode,
pattern: "*.bam",
enabled: params.save_assembly_mapped_reads,
],
]
}

withName: 'SAMTOOLS_COVERM_SHORTREAD_INDEX' {
publishDir = [
path: { "${params.outdir}/Assembly/${meta.assembler}/QC/${meta.id}" },
mode: params.publish_dir_mode,
pattern: "*.bai",
enabled: params.save_assembly_mapped_reads,
]
}

withName: 'SAMTOOLS_COVERM_LONGREAD_INDEX' {
publishDir = [
path: { "${params.outdir}/GenomeBinning/depths/contigs" },
path: { "${params.outdir}/Assembly/${meta.assembler}/QC/${meta.id}" },
mode: params.publish_dir_mode,
pattern: '*-depth.txt.gz',
pattern: "*.bai",
enabled: params.save_assembly_mapped_reads,
]
}

Expand Down
26 changes: 26 additions & 0 deletions conf/test_coverm_shortread.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
========================================================================================
Nextflow config file for testing CoverM native short-read coverage mapping
========================================================================================
*/

includeConfig 'test.config'

params {
config_profile_name = 'Test CoverM short-read profile'
config_profile_description = 'Minimal test dataset using CoverM native short-read mapping'

shortread_coverage_mapper = 'minimap2-sr'
save_assembly_mapped_reads = true
skip_clipping = true
keep_phix = true
skip_semibin = true
skip_prokka = true
skip_quast = true
skip_binqc = true
run_busco = false
run_checkm = false
run_checkm2 = false
skip_gtdbtk = true
cat_db = null
}
10 changes: 3 additions & 7 deletions conf/test_full.config
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ process {
memory = { 2.GB * task.attempt }
errorStrategy = { task.exitStatus in [1, 255] ? 'ignore' : 'retry' }
}
withName: 'NFCORE_MAG:MAG:BINNING:METABAT2_JGISUMMARIZEBAMCONTIGDEPTHS_LONGREAD' {
withName: 'NFCORE_MAG:MAG:BINNING_PREPARATION:LONGREAD_BINNING_PREPARATION:COVERM_CONTIG_LONGREAD' {
cpus = { 3 * task.attempt }
memory = { 1.GB * task.attempt }
}
withName: 'NFCORE_MAG:MAG:BINNING:METABAT2_JGISUMMARIZEBAMCONTIGDEPTHS_SHORTREAD' {
withName: 'NFCORE_MAG:MAG:BINNING_PREPARATION:SHORTREAD_BINNING_PREPARATION:COVERM_CONTIG_SHORTREAD' {
cpus = { 3 * task.attempt }
memory = { 1.GB * task.attempt }
}
Expand All @@ -118,11 +118,7 @@ process {
cpus = { 18 * task.attempt }
memory = { 1.GB * task.attempt }
}
withName: 'NFCORE_MAG:MAG:BINNING_PREPARATION:LONGREAD_BINNING_PREPARATION:MINIMAP2_ASSEMBLY_ALIGN' {
cpus = { 13 * task.attempt }
memory = { 17.GB * task.attempt }
}
withName: 'NFCORE_MAG:MAG:BINNING_PREPARATION:LONGREAD_BINNING_PREPARATION:MINIMAP2_ASSEMBLY_INDEX' {
withName: 'NFCORE_MAG:MAG:BINNING_PREPARATION:LONGREAD_BINNING_PREPARATION:SAMTOOLS_COVERM_LONGREAD_INDEX' {
cpus = { 1 * task.attempt }
memory = { 2.GB * task.attempt }
}
Expand Down
6 changes: 4 additions & 2 deletions docs/output.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,15 +361,17 @@ Protein-coding genes are predicted for each assembly.

### Contig sequencing depth

Sequencing depth per contig and sample is generated by MetaBAT2's `jgi_summarize_bam_contig_depths --outputDepth`. The values correspond to `(sum of exactly aligned bases) / ((contig length)-2*75)`. For example, for two reads aligned exactly with `10` and `9` bases on a 1000 bp long contig the depth is calculated by `(10+9)/(1000-2*75)` (1000bp length of contig minus 75bp from each end, which is excluded).
Sequencing depth per contig and sample is generated by [CoverM](https://github.com/wwood/CoverM) using the `metabat` method (equivalent to MetaBAT2's `jgi_summarize_bam_contig_depths --outputDepth`). The values correspond to `(sum of exactly aligned bases) / ((contig length)-2*75)`. For example, for two reads aligned exactly with `10` and `9` bases on a 1000 bp long contig the depth is calculated by `(10+9)/(1000-2*75)` (1000bp length of contig minus 75bp from each end, which is excluded).

The legacy `jgi_summarize_bam_contig_depths` tool from MetaBAT2 can still be used by setting `--depth_calculator metabat2`.

These depth files are used for downstream binning steps.

<details markdown="1">
<summary>Output files</summary>

- `GenomeBinning/depths/contigs/`
- `[assembler]-[sample/group]-depth.txt.gz`: Sequencing depth for each contig and sample or group, only for short reads.
- `[assembler]-[sample/group]-depth.tsv`: Sequencing depth for each contig and sample or group.

</details>

Expand Down
20 changes: 16 additions & 4 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -437,12 +437,24 @@ This may result in a different set or none of contigs being evaluated in pyDamag

In order to run the binning tools included in the pipeline, MAG must first align reads back to the assemblies, and estimate the coverage of each contig.

During the coverage estimation step, these alignments are by default filtered to retain alignments that have a percentage identity of 97% (i.e., of the base pairs that match between the read and the contig, 97% are identical). This value is a good default for short read Illumina data, however for certain long read technologies, the error rates in the reads can be much higher.
For example, older Oxford Nanopore chemistries can have error rates approaching
15% - 20%.
The pipeline uses [CoverM](https://github.com/wwood/CoverM) for coverage estimation. CoverM outputs a MetaBAT2-compatible depth file (using `--methods metabat`) which is compatible with all downstream binning tools.

### Mapper selection

The `--shortread_coverage_mapper` parameter controls which aligner is used for mapping short reads back to assembled contigs:

- `bowtie2` (default): Runs Bowtie2 manually to produce BAM files, which are then passed to CoverM.
- CoverM-native short-read mappers (`bwa-mem`, `bwa-mem2`, `minimap2-sr`, `strobealign`): CoverM handles both mapping and coverage calculation directly from reads and exports cached BAM files for downstream binners.

Long-read coverage mapping is handled by CoverM automatically from the samplesheet `long_reads_platform` metadata, using `minimap2-ont` for Oxford Nanopore reads, `minimap2-pb` for PacBio CLR reads, and `minimap2-hifi` for PacBio HiFi reads.

### Alignment identity filtering

During the coverage estimation step, alignments are by default filtered to retain alignments that have a percentage identity of 97% (i.e., of the base pairs that match between the read and the contig, 97% are identical). This value is a good default for short read Illumina data, however for certain long read technologies, the error rates in the reads can be much higher.
For example, older Oxford Nanopore chemistries can have error rates approaching 15% - 20%.

If you are having trouble with the coverage estimation steps (for example, the output depths for each bin are all at or near zero), it may be worth manually adjusting this parameter, if it is appropriate for your data.
You can do this by adjusting the `--longread_percentidentity` and `--shortread_percentidentity` parameters for long reads and short reads, respectively.
You can do this by adjusting the `--longread_percentidentity` and `--shortread_percentidentity` parameters for long reads and short reads, respectively. These set CoverM's `--min-read-percent-identity` flag.
For older ONT data, you may wish to look at values of around 85% to improve coverage estimation.

## A note on bin refinement
Expand Down
5 changes: 5 additions & 0 deletions modules.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@
"git_sha": "e753770db613ce014b3c4bc94f6cba443427b726",
"installed_by": ["fasta_binning_concoct"]
},
"coverm/contig": {
"branch": "master",
"git_sha": "38c52b07d406618f6ba4bb21e80172e0230c5623",
"installed_by": ["modules"]
},
"dastool/dastool": {
"branch": "master",
"git_sha": "e753770db613ce014b3c4bc94f6cba443427b726",
Expand Down
14 changes: 9 additions & 5 deletions modules/local/mag_depths_convert/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,25 @@ process CONVERT_DEPTHS {
path "versions.yml" , emit: versions

script:
def depth_unzipped = depth.toString() - '.gz'
"""
gunzip -f ${depth}
# Decompress only if gzipped
if [[ "${depth}" == *.gz ]]; then
gunzip -f "${depth}"
fi

# Determine the number of abundance columns
n_abund=\$(awk 'NR==1 {print int((NF-3)/2)}' ${depth.toString() - '.gz'})
n_abund=\$(awk 'NR==1 {print int((NF-3)/2)}' ${depth_unzipped})

# Get column names
read -r header<${depth.toString() - '.gz'}
read -r header<${depth_unzipped}
header=(\$header)

# Generate abundance files for each read set
for i in \$(seq 1 \$n_abund); do
col=\$((i*2+2))
name=\$( echo \${header[\$col-1]} | sed s/\\.bam\$// )
bioawk -t '{if (NR > 1) {print \$1, \$'"\$col"'}}' ${depth.toString() - '.gz'} > \${name}.abund
name=\$( basename "\${header[\$col-1]}" | sed s/\\.bam\$// )
bioawk -t '{if (NR > 1) {print \$1, \$'"\$col"'}}' ${depth_unzipped} > \${name}.abund
done

cat <<-END_VERSIONS > versions.yml
Expand Down
7 changes: 7 additions & 0 deletions modules/nf-core/coverm/contig/environment.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 53 additions & 0 deletions modules/nf-core/coverm/contig/main.nf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading