Metagenomic Assembly, Binning, and MAGs
When to Use
- Assembling shotgun metagenomic reads (post-QC/decontamination) into contigs.
- Recovering metagenome-assembled genomes (MAGs) from a microbial community sample.
- Choosing/comparing binners (MetaBAT2, CONCOCT, MaxBin2) or dereplicating with DAS_Tool.
- Grading bin quality (completeness/contamination) against the MIMAG standard before deposition or downstream analysis.
- Deciding between single-sample vs multi-sample (co-abundance) binning strategy.
Version Compatibility
MEGAHIT ≥ 1.2.9, metaSPAdes (SPAdes) ≥ 3.15, MetaBAT2 ≥ 2.15, CONCOCT ≥ 1.1, MaxBin2 ≥ 2.2.7, DAS_Tool ≥ 1.1.6, CheckM ≥ 1.2 (or CheckM2 ≥ 1.0), bowtie2 ≥ 2.5, samtools ≥ 1.17, Python ≥ 3.10 with pandas/numpy for downstream QC.
Prerequisites
- Reads already quality-trimmed and host/contaminant-screened (see
bio-read-qc-contamination-screening). - Tools on
PATH:megahit,bowtie2,samtools,jgi_summarize_bam_contig_depths(ships with MetaBAT2),metabat2,das_tool,checkm. pandas,numpyfor parsing depth tables and CheckM output in Python.
Workflow Overview
reads → MEGAHIT assembly → filter ≥500 bp contigs
→ map reads back → jgi_summarize_bam_contig_depths
→ MetaBAT2/CONCOCT/MaxBin2 binning
→ DAS_Tool dereplication
→ CheckM quality assessment
→ filter HQ MAGs (≥90% complete, <5% contamination)
Goal: turn decontaminated paired-end reads into a set of genome-resolved MAGs. Approach: assemble once with MEGAHIT (fast, low RAM), recruit coverage signal by mapping reads back, bin with multiple tools and dereplicate with DAS_Tool, then gate bins on CheckM's MIMAG tiers.
# 1. Assembly
megahit \
-1 decontam_1.fastq.gz \
-2 decontam_2.fastq.gz \
-o megahit_assembly/ \
--min-contig-len 500 \
--k-list 21,29,39,59,79,99,119,141 \
-t 16 \
-m 0.5 # cap at 50% of available RAM
seqkit stats megahit_assembly/final.contigs.fa
# 2. Coverage estimation (map reads back to own assembly)
bowtie2-build megahit_assembly/final.contigs.fa contigs_index
bowtie2 -x contigs_index -1 decontam_1.fastq.gz -2 decontam_2.fastq.gz \
-p 16 --no-unal | samtools sort -@ 8 -o contigs_mapped.bam
samtools index contigs_mapped.bam
# For multi-sample binning: repeat mapping for each sample's BAM,
# then pass ALL bams to jgi_summarize_bam_contig_depths in one call.
jgi_summarize_bam_contig_depths \
--outputDepth depths.txt \
contigs_mapped.bam
# columns: contigName, contigLen, totalAvgDepth, sample1.bam, sample1.bam-var, ...
# 3. Binning (run multiple binners, then dereplicate)
metabat2 \
-i megahit_assembly/final.contigs.fa \
-a depths.txt \
-o bins/bin \
--minContig 1500 \
--minClsSize 100000 \
-t 8 --saveCls
das_tool \
-i metabat2_bins,concoct_bins,maxbin2_bins \
-l MetaBAT2,CONCOCT,MaxBin2 \
-c megahit_assembly/final.contigs.fa \
-o dastool_output/ \
-t 8 --write_bins
# 4. Quality assessment
checkm lineage_wf dastool_output/_DASTool_bins/ checkm_out/ -x fa -t 16 --pplacer_threads 4
checkm qa checkm_out/lineage.ms checkm_out/ -o 2 > checkm_summary.txt
Binning signals used by MetaBAT2/CONCOCT:
- Tetranucleotide frequency (TNF) — 256-dim composition vector, genome-specific.
- Coverage depth across samples — organism-specific abundance (multi-sample = differential coverage = much cleaner bins).
MIMAG Quality Tiers (Bowers et al. 2017, Nature Biotechnology)
| Tier | Completeness | Contamination |
|---|---|---|
| High quality | ≥ 90% | < 5% |
| Medium quality | ≥ 50% | < 10% |
| Low quality | < 50% | — |
CheckM estimates completeness/contamination from ~100 lineage-specific single-copy marker genes expected exactly once in a complete genome; the marker set is chosen from each bin's phylogenetic placement.
Goal: parse assembly/CheckM output and classify bins programmatically instead of eyeballing text reports.
Approach: compute N50 from contig lengths, then apply the MIMAG completeness/contamination thresholds to a CheckM qa table.
import numpy as np
import pandas as pd
def compute_n50(contig_lengths: np.ndarray) -> int:
"""Return the N50 of an assembly given an array of contig lengths (bp).
N50 = length of the contig at which the cumulative sum of all contig
lengths, sorted longest-first, first reaches 50% of the total assembly.
"""
lengths_sorted = np.sort(contig_lengths)[::-1]
cumsum = np.cumsum(lengths_sorted)
half_total = cumsum[-1] / 2
n50_idx = np.searchsorted(cumsum, half_total)
return int(lengths_sorted[n50_idx])
def mimag_quality_tier(completeness: float, contamination: float) -> str:
"""Classify a MAG into a MIMAG tier from CheckM completeness/contamination (%)."""
if completeness >= 90 and contamination < 5:
return "High Quality"
elif completeness >= 50 and contamination < 10:
return "Medium Quality"
return "Low Quality"
# Parse `checkm qa -o 2` tab-separated output
checkm_df = pd.read_csv("checkm_summary.txt", sep="\t")
checkm_df = checkm_df.rename(columns=lambda c: c.strip())
checkm_df["Quality"] = checkm_df.apply(
lambda row: mimag_quality_tier(row["Completeness"], row["Contamination"]), axis=1
)
print(checkm_df["Quality"].value_counts())
hq_bins = checkm_df[checkm_df["Quality"] == "High Quality"]
print(f"High-quality MAGs: {len(hq_bins)} / {len(checkm_df)}")
Binner Comparison
| Binner | Signal used | Strengths |
|---|---|---|
| MetaBAT2 | TNF + coverage | Fast, widely used, good default |
| CONCOCT | TNF + coverage (PCA-reduced) | Good for low-coverage genomes |
| MaxBin2 | Marker gene abundance + coverage | Marker-guided initialization |
| DAS_Tool | Dereplicates all of the above | Best final MAG set; always run this last |
Pitfalls
- Discard short contigs before binning: contigs < 1500 bp carry insufficient TNF signal for reliable clustering — use
--minContig 1500in MetaBAT2. - Multi-sample binning dramatically improves quality: map all samples to the same assembly and feed all BAMs to
jgi_summarize_bam_contig_depthsin one call whenever you have ≥2 related samples — differential coverage is the strongest binning signal. - Strain heterogeneity ≠ contamination: high CheckM contamination with high strain heterogeneity (≥90% AA identity between duplicated marker genes) indicates strain mixing within one population, not foreign contamination.
- Run all three binners, then DAS_Tool: MetaBAT2 alone leaves quality on the table; DAS_Tool-dereplicated bins from MetaBAT2 + CONCOCT + MaxBin2 consistently outperform any single binner.
- MEGAHIT vs metaSPAdes trade-off: MEGAHIT is RAM-efficient and fast; metaSPAdes is more accurate for low-coverage organisms but needs 100–400 GB RAM for complex communities.
- N50 expectations: a typical gut metagenome (5 Gbp data) assembles to ~100k–500k contigs with N50 of 1–10 kb — don't expect chromosome-scale contigs from short-read metagenomics.
- CheckM marker sets can mislead novel taxa: if a bin's closest reference lineage is distant, completeness/contamination estimates from generic (domain-level) marker sets are unreliable — use CheckM2 (ML-based, marker-set-free) for highly novel MAGs.
See Also
bio-applied-genome-assemblybio-applied-taxonomic-profilingmetagenomics-shotgunbio-applied-microbial-diversity