Skip to content
Back to skills

Metagenomics Shotgun

ASecurity

Shotgun metagenomics — host decontamination, Kraken2 taxonomic profiling, Bracken abundance, HUMAnN3 functional annotation, MEGAHIT assembly, MetaBAT2 binning, CheckM, MAGs, QIIME2 16S

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 27, 2026
data-aipythonbashexpresstestingdatabase

Works with

  • cli

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add Pavel-Kravchenko/Bioinformatics --skill metagenomics-shotgun --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Metagenomics Shotgun?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Metagenomics Shotgun
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/pavel-kravchenko-metagenomics-shotgun/badge)](https://www.skillsdirectory.com/skills/pavel-kravchenko-metagenomics-shotgun)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: metagenomics-shotgun
description: Shotgun metagenomics — host decontamination, Kraken2 taxonomic profiling, Bracken abundance, HUMAnN3 functional annotation, MEGAHIT assembly, MetaBAT2 binning, CheckM, MAGs, QIIME2 16S
tool_type: python
primary_tool: NumPy
---

# Metagenomics (Shotgun  16S)

## When to Use

Use this skill when:
- Processing whole-metagenome shotgun sequencing (WMS) data
- Performing taxonomic profiling beyond 16S (species/strain resolution)
- Annotating community functional pathways
- Recovering metagenome-assembled genomes (MAGs)
- Running 16S amplicon analysis with QIIME2

## Quick Reference

| Task | Tool | Key Command |
|------|------|-------------|
| Host decontamination | Bowtie2 | `bowtie2 --un-conc-gz decontam` |
| Taxonomic profiling | Kraken2 | `kraken2 --report report.txt` |
| Abundance re-estimation | Bracken | `bracken -d db -i report.txt -l S` |
| Functional pathways | HUMAnN3 | `humann --input reads.fq.gz` |
| Assembly | MEGAHIT | `megahit -1 R1 -2 R2 --min-contig-len 500` |
| Binning | MetaBAT2 | `metabat2 -i contigs.fa -a depths.txt` |
| Bin QC | CheckM | `checkm lineage_wf bins/ out/` |
| MAG annotation | Prokka | `prokka --metagenome bin.fa` |
| 16S analysis | QIIME2 | `qiime dada2 denoise-paired` |

## Key Patterns

**Pattern 1: Taxonomic profiling pipeline**
```bash
# Remove host reads
bowtie2 -x hg38 -1 R1.fq.gz -2 R2.fq.gz \
    --un-conc-gz decontam_%.fq.gz > /dev/null

# Kraken2 classification
kraken2 --db standard/ --paired --gzip-compressed \
    decontam_1.fq.gz decontam_2.fq.gz \
    --report kraken2_report.txt --output kraken2_out.txt

# Bracken species-level re-estimation
bracken -d standard/ -i kraken2_report.txt \
    -o bracken_species.txt -r 150 -l S -t 10
```

**Pattern 2: Functional annotation with HUMAnN3**
```bash
humann --input decontam_merged.fq.gz \
    --output humann3_out/ --threads 8

# Normalize pathways
humann_renorm_table --input humann3_out/sample_pathabundance.tsv \
    --output pathways_cpm.tsv --units cpm

# Join multiple samples
humann_join_tables --input humann3_outputs/ \
    --output all_pathways.tsv --file_name pathabundance
```

**Pattern 3: Assembly and binning**
```bash
# Assembly
megahit -1 decontam_1.fq.gz -2 decontam_2.fq.gz \
    -o megahit/ --min-contig-len 500 -t 16

# Coverage for binning
bowtie2-build megahit/final.contigs.fa contigs_index
bowtie2 -x contigs_index -1 decontam_1.fq.gz -2 decontam_2.fq.gz | \
    samtools sort -o contigs.bam && samtools index contigs.bam

# Binning with MetaBAT2
jgi_summarize_bam_contig_depths --outputDepth depths.txt contigs.bam
metabat2 -i megahit/final.contigs.fa -a depths.txt -o bins/bin --minContig 1500

# CheckM quality
checkm lineage_wf bins/ checkm_out/ -t 8 -x fa
```

**Pattern 4: QIIME2 16S workflow (CLI)**
```bash
# Import paired-end reads
qiime tools import \
    --type 'SampleData[PairedEndSequencesWithQuality]' \
    --input-path manifest.csv \
    --output-path reads.qza \
    --input-format PairedEndFastqManifestPhred33V2

# DADA2 denoising
qiime dada2 denoise-paired \
    --i-demultiplexed-seqs reads.qza \
    --p-trunc-len-f 250 --p-trunc-len-r 200 \
    --o-table table.qza --o-representative-sequences rep_seqs.qza

# Taxonomy classification
qiime feature-classifier classify-sklearn \
    --i-classifier silva138_classifier.qza \
    --i-reads rep_seqs.qza --o-classification taxonomy.qza

# Diversity
qiime diversity core-metrics-phylogenetic \
    --i-table table.qza --i-phylogeny rooted_tree.qza \
    --p-sampling-depth 5000 --m-metadata-file metadata.tsv \
    --output-dir diversity/
```

## MAG Quality Standards (MIMAG)

| Tier | Completeness | Contamination |
|------|-------------|---------------|
| High quality | ≥ 90% | < 5% |
| Medium quality | ≥ 50% | < 10% |
| Low quality | < 50% | — |

## Key Patterns (Diversity Analysis)

### Alpha Diversity Metrics
```python
import numpy as np

def shannon_diversity(counts):
    """Shannon H' — richness + evenness."""
    counts = np.array(counts, dtype=float)
    p = counts[counts > 0] / counts[counts > 0].sum()
    return -np.sum(p * np.log(p))

def simpson_diversity(counts):
    """Simpson 1-D — probability two reads differ; robust to rare taxa."""
    counts = np.array(counts, dtype=float)
    p = counts[counts > 0] / counts[counts > 0].sum()
    return 1 - np.sum(p ** 2)

def observed_richness(counts):
    return int(np.sum(np.array(counts) > 0))
```

| Metric | Formula | Notes |
|--------|---------|-------|
| Observed species | `count(counts > 0)` | Richness only |
| Shannon H' | `-Σ pᵢ ln(pᵢ)` | Richness + evenness; 0 = no diversity |
| Simpson 1-D | `1 - Σ pᵢ²` | Probability two reads differ; robust to rare taxa |
| Faith's PD | `Σ branch lengths (observed taxa)` | Phylogenetic richness |

### Beta Diversity: Bray-Curtis Distance
```python
def bray_curtis(s1, s2):
    s1, s2 = np.array(s1, float), np.array(s2, float)
    return np.sum(np.abs(s1 - s2)) / np.sum(s1 + s2)
```

| Metric | Phylogenetic | Quantitative |
|--------|:-----------:|:------------:|
| Jaccard | No | No |
| Bray-Curtis | No | Yes |
| Unweighted UniFrac | Yes | No |
| Weighted UniFrac | Yes | Yes |

## Code Templates

### Parse Kraken2 Report
```python
import pandas as pd

def read_kraken2_report(path):
    cols = ['pct', 'clade_reads', 'direct_reads', 'rank', 'taxid', 'name']
    df = pd.read_csv(path, sep='\t', header=None, names=cols)
    df['name'] = df['name'].str.strip()
    return df

report = read_kraken2_report('kraken2_report.txt')
species = report[report['rank'] == 'S'].sort_values('pct', ascending=False)
print(species[['name', 'pct']].head(10).to_string(index=False))
```

### Alpha Diversity from OTU Table
```python
import pandas as pd

otu_table = pd.read_csv('otu_table.tsv', sep='\t', index_col=0)
alpha = pd.DataFrame({
    'shannon': otu_table.apply(shannon_diversity, axis=1),
    'simpson': otu_table.apply(simpson_diversity, axis=1),
    'richness': otu_table.apply(observed_richness, axis=1),
})
print(alpha.describe())
```

### Bray-Curtis Distance Matrix & PCoA
```python
from scipy.spatial.distance import braycurtis
import numpy as np

otu = pd.read_csv('otu_table.tsv', sep='\t', index_col=0)
otu_rel = otu.div(otu.sum(axis=1), axis=0)

n = len(otu_rel)
dist = np.zeros((n, n))
for i in range(n):
    for j in range(i + 1, n):
        d = braycurtis(otu_rel.iloc[i], otu_rel.iloc[j])
        dist[i, j] = dist[j, i] = d

def pcoa(dm: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
    """Classical PCoA. Returns (coords n×2, proportion_explained[:2])."""
    n = len(dm)
    H = np.eye(n) - np.ones((n, n)) / n
    B = -0.5 * H @ (dm ** 2) @ H
    eigvals, eigvecs = np.linalg.eigh(B)
    idx = np.argsort(eigvals)[::-1]
    eigvals, eigvecs = eigvals[idx], eigvecs[:, idx]
    pos = eigvals > 0
    coords = eigvecs[:, pos] * np.sqrt(eigvals[pos])
    prop = eigvals[pos] / eigvals[pos].sum()
    return coords[:, :2], prop[:2]

coords, prop = pcoa(dist)
```

### PERMANOVA
```python
def permanova(dm: np.ndarray, grouping: np.ndarray,
              n_perm: int = 999) -> tuple[float, float]:
    """Returns (F-statistic, p-value)."""
    unique = np.unique(grouping)
    n = len(grouping)

    def f_stat(g):
        ss_tot = np.sum(dm ** 2) / n
        ss_w = sum(
            np.sum(dm[np.ix_(g == grp, g == grp)] ** 2) / (2 * (g == grp).sum())
            for grp in unique if (g == grp).sum() > 1
        )
        df_b, df_w = len(unique) - 1, n - len(unique)
        return ((ss_tot - ss_w) / df_b) / (ss_w / df_w) if df_w and ss_w else 0.0

    obs = f_stat(grouping)
    perm_count = sum(f_stat(np.random.permutation(grouping)) >= obs
                     for _ in range(n_perm))
    return obs, (perm_count + 1) / (n_perm + 1)
```

### CheckM TSV Parser
```python
def read_checkm(path):
    """Parse CheckM lineage_wf output qa file."""
    df = pd.read_csv(path, sep='\t')
    df.columns = [c.strip().lower().replace(' ', '_') for c in df.columns]
    high_q = df[(df['completeness'] >= 90) & (df['contamination'] < 5)]
    med_q  = df[(df['completeness'] >= 50) & (df['contamination'] < 10)]
    print(f"High-quality MAGs: {len(high_q)}")
    print(f"Medium-quality MAGs: {len(med_q)}")
    return df
```

## Pitfalls

- **Host decontamination is critical** — failure to remove host reads inflates classifications
- **Kraken2 database choice** — standard (archaea + bacteria + viral) vs PlusPF (adds protozoa/fungi) vs custom
- **Bracken threshold** — `-t 10` requires ≥10 reads assigned to a taxon; lower for low-coverage samples
- **HUMAnN3 databases** — must download UniRef90 and ChocoPhlAn databases (~25 GB) separately
- **Binning quality** — MetaBAT2 needs ≥2× coverage and ≥500 bp contigs; CONCOCT or MaxBin2 can be combined (DAS Tool for bin refinement)
- **Rarefying without checking curves** — rarefy only when rarefaction curves plateau; otherwise you discard real signal
- **Comparing raw alpha diversity without rarefaction** — deeper-sequenced samples will always appear more diverse
- **PERMANOVA sensitivity to dispersion** — PERMANOVA is sensitive to differences in within-group variance (not just centroids). Pair with a dispersion test (`betadisper` in R)

## Related Skills
- `ngs-variant-calling` — FASTQ QC, short-read alignment, samtools
- `rnaseq` — RNA-seq differential expression, DESeq2/edgeR
- `python-core-bio` — FASTA/FASTQ parsing, sequence manipulation
- `biostatistics-r` — statistical testing, diversity analysis in R

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.