| name | bio-metagenomics-strain-tracking |
| description | Track bacterial strains using MASH, sourmash, fastANI, and inStrain. Compare genomes, detect contamination, and monitor strain-level variation. Use when needing sub-species resolution for outbreak tracking, transmission analysis, or within-host strain dynamics. |
| tool_type | cli |
| primary_tool | MASH |
Strain Tracking
Identify and track bacterial strains at sub-species resolution.
Tool Comparison
| Tool | Method | Best For |
|---|
| MASH | MinHash sketches | Fast distance estimation |
| sourmash | MinHash + containment | Metagenome comparisons |
| fastANI | ANI calculation | Accurate species/strain ID |
| inStrain | SNV profiling | Strain dynamics in metagenomes |
MASH
Installation
conda install -c bioconda mash
Create Sketch
mash sketch -o genome.msh genome.fasta
mash sketch -o reference_db.msh genomes/*.fasta
mash sketch -m 2 -r -o reads.msh reads.fastq.gz
Calculate Distance
mash dist genome1.fasta genome2.fasta
mash dist reference_db.msh query.fasta > distances.tsv
mash screen reference_db.msh reads.fastq.gz > screen_results.tsv
Interpret MASH Distance
| Distance | Interpretation |
|---|
| < 0.05 | Same species/strain |
| 0.05-0.15 | Same species |
| 0.15-0.25 | Same genus |
| > 0.25 | Different genus |
Cluster Genomes
mash triangle genomes/*.fasta > distances.phylip
mash triangle -E genomes/*.fasta > distances.tsv
sourmash
Installation
conda install -c bioconda sourmash
Create Signatures
sourmash sketch dna -p scaled=1000,k=31 genome.fasta -o genome.sig
sourmash sketch dna -p scaled=1000,k=31 genomes/*.fasta -o genomes.sig
sourmash sketch protein -p scaled=100,k=10 proteins.faa -o proteins.sig
Compare Signatures
sourmash compare *.sig -o comparison.npy --csv comparison.csv
sourmash search query.sig database.sig --threshold 0.8
sourmash gather metagenome.sig database.sig -o gather_results.csv
Taxonomy Assignment
sourmash database download gtdb-rs214-k31.zip
sourmash lca classify --db gtdb-rs214-k31.lca.json.gz --query query.sig
sourmash lca summarize --db gtdb-rs214-k31.lca.json.gz --query metagenome.sig
fastANI
Installation
conda install -c bioconda fastani
Calculate ANI
fastANI -q query.fasta -r reference.fasta -o ani_result.txt
fastANI -q query.fasta --rl reference_list.txt -o ani_results.txt
fastANI --ql genome_list.txt --rl genome_list.txt -o all_vs_all.txt --matrix
Interpret ANI
| ANI | Interpretation |
|---|
| >99% | Same strain |
| 95-99% | Same species |
| <95% | Different species |
inStrain
For strain-level analysis in metagenomes.
Installation
conda install -c bioconda instrain
Profile Strains
bowtie2 -x reference -1 reads_1.fq -2 reads_2.fq | \
samtools sort -o mapped.bam
inStrain profile mapped.bam reference.fasta -o instrain_output -p 8
Compare Samples
for bam in sample*.bam; do
inStrain profile $bam reference.fasta -o ${bam%.bam}_IS -p 8
done
inStrain compare -i sample*_IS -o comparison_IS -p 8
Key Outputs
cat instrain_output/output/SNVs.tsv
cat instrain_output/output/gene_info.tsv
cat instrain_output/output/genome_info.tsv
Complete Workflow: Outbreak Tracking
#!/bin/bash
set -euo pipefail
GENOMES_DIR=$1
OUTPUT_DIR=$2
mkdir -p $OUTPUT_DIR
echo "=== MASH sketching ==="
mash sketch -o $OUTPUT_DIR/genomes.msh $GENOMES_DIR/*.fasta
echo "=== MASH distances ==="
mash dist $OUTPUT_DIR/genomes.msh $OUTPUT_DIR/genomes.msh > $OUTPUT_DIR/mash_distances.tsv
echo "=== fastANI ==="
ls $GENOMES_DIR/*.fasta > $OUTPUT_DIR/genome_list.txt
fastANI --ql $OUTPUT_DIR/genome_list.txt \
--rl $OUTPUT_DIR/genome_list.txt \
-o $OUTPUT_DIR/fastani_results.txt \
--matrix
echo "=== sourmash signatures ==="
sourmash sketch dna -p scaled=1000,k=31 $GENOMES_DIR/*.fasta -o $OUTPUT_DIR/all.sig
sourmash compare $OUTPUT_DIR/all.sig -o $OUTPUT_DIR/sourmash.npy --csv $OUTPUT_DIR/sourmash.csv
echo "=== Identify clusters ==="
python3 << 'EOF'
import pandas as pd
import numpy as np
mash = pd.read_csv('${OUTPUT_DIR}/mash_distances.tsv', sep='\t', header=None,
names=['ref', 'query', 'distance', 'pvalue', 'shared'])
close = mash[(mash['distance'] < 0.001) & (mash[] != mash[])]
()
(close[[, , ]])
EOF
Python Analysis
import pandas as pd
import numpy as np
from scipy.cluster.hierarchy import linkage, fcluster
from scipy.spatial.distance import squareform
mash = pd.read_csv('mash_distances.tsv', sep='\t', header=None,
names=['ref', 'query', 'dist', 'pval', 'shared'])
samples = sorted(set(mash['ref'].tolist()))
dist_matrix = mash.pivot(index='ref', columns='query', values='dist').fillna(0)
dist_matrix = dist_matrix.loc[samples, samples]
condensed = squareform(dist_matrix.values)
Z = linkage(condensed, method='average')
clusters = fcluster(Z, t=0.05, criterion='distance')
cluster_df = pd.DataFrame({'sample': samples, 'cluster': clusters})
print(cluster_df.groupby('cluster').size())
Related Skills
- metagenomics/kraken-classification - Taxonomic classification
- genome-assembly/contamination-detection - Contamination screening
- phylogenetics/modern-tree-inference - Phylogenetic analysis
- metagenomics/metaphlan-profiling - Species profiling