Skip to content

Repository files navigation

distree

License: GPL v3 distree Anaconda-Server Badge Anaconda-Version Badge PGO DOI

Paula Ruiz-Rodriguez1 and Mireia Coscolla1
1. I2SysBio, University of Valencia-CSIC, FISABIO Joint Research Unit Infection and Public Health, Valencia, Spain

distree reads a phylogenetic tree in Newick format and writes the pairwise distance between every pair of tips: patristic (summed branch lengths), topological (edge counts), or the variance-covariance matrix a comparative model wants. Rows stream out as they are computed, so memory grows with the number of tips rather than with the square of it.

📖 Full documentation: https://pathogenomics-lab.github.io/distree/

Page Description
Quick start The handful of commands most runs actually use
Tutorial A worked outbreak investigation, tree to transmission clusters
Input What Newick is accepted, what is rejected, and why
Distance modes Patristic, topological and var-covar, on one worked example
Midpoint rooting When the root changes the answer, and when it cannot
Output TSV, PHYLIP lower triangle, NumPy arrays, precision
CLI reference Every flag, every default, every message
How it works The parser, the LCA structure, the streaming loop
Performance Measured speed, memory and thread scaling
Recipes PCoA, transmission clusters, PGLS, neighbour-joining

Installation

# Bioconda
conda install -c bioconda distree

# From source
cargo build --release

Prebuilt binaries for Linux and macOS, x86-64 and arm64, are on the releases page.

Quick start

# Patristic distances, as a tab-separated matrix
distree tree.nwk -o distances.tsv

# Six decimals across eight threads, PHYLIP lower triangle
distree tree.nwk --lower -p 6 -t 8 -o distances.phy

# Edge counts instead of branch lengths
distree tree.nwk --topology -o topology.tsv

# The variance-covariance matrix for PGLS, midpoint-rooted
distree tree.nwk --midpoint --lmm -o varcovar.tsv

# A NumPy array: exact, half the size of text, and 2.6x faster
distree tree.nwk --npy -o distances.npy

# The condensed vector scipy.cluster.hierarchy reads directly
distree tree.nwk --lower --npy -o condensed.npy

# Just the samples in a list, from a gzipped tree
distree tree.nwk.gz --taxa cohort.txt --stats -o cohort.tsv

# From stdin
gunzip -c tree.nwk.gz | distree - -o distances.tsv

What it does

Patristic The sum of branch lengths on the path between two tips
Topological The number of edges on that path, ignoring branch lengths
Variance-covariance The root-to-MRCA distance for each pair, the C matrix of a PGLS or phylogenetic mixed model
Rooting Optional midpoint rooting, which matters for --lmm and cannot matter for the other two
Formats Square TSV, PHYLIP lower triangle, or a NumPy .npy array
Input Newick from a file or stdin, plain or gzipped, with quoted labels, polytomies, NHX and BEAST comments, and UTF-8 tip names
Subsets --taxa restricts the matrix to a list of tips, with the distances the full tree gives
Scale Rows stream out as they are computed; memory tracks the tips, not the matrix
Parallelism Distances and their formatting both spread across cores

It works on the tree you give it: it does not build one, does not read an alignment, and does not cluster the matrix for you. It also does not guess. A truncated tree, a file holding several trees, an unclosed quote or a label with a tab in it are rejected with the position, rather than turned into a matrix that looks right and is not.

Performance

Balanced trees, -p 6 --lower, release build on an Apple M4 Pro with 14 cores.

Tips Cells Time Peak memory
1,000 0.5 M 0.00 s 11 MB
8,000 32 M 0.13 s 32 MB
20,000 200 M 1.02 s 35 MB

Memory flattens out because nothing holds the matrix: past a few thousand tips it is the LCA table plus one batch of rows. --npy is another 2.6x on top, at full precision and half the file size. Full numbers, thread scaling and the memory arithmetic are here.

Correctness

Distances are cross-validated against R's ape over generated trees: cophenetic.phylo for patristic, vcv.phylo for variance-covariance, cophenetic.phylo over unit branch lengths for edge counts, and phangorn::midpoint for the rooting. All four agree to under 1e-9, which is the text round-trip, and exactly for edge counts. The parser and the pipeline are fuzzed. See Contributing.

Citation

Ruiz-Rodriguez P, Coscolla M. distree: distance matrices from a phylogeny. PathoGenOmics Lab. doi:10.5281/zenodo.16811766

Please record the version and the mode you used: a patristic matrix, a topological one and a variance-covariance matrix are three different objects.

License

GPL-3.0.


distree is developed with ❤️ by:

Paula Ruiz-Rodriguez

💻 🔬 🤔 🔣 🎨 🔧

Mireia Coscolla

🔍 🤔 🧑‍🏫 🔬 📓

This project follows the all-contributors specification (emoji key).

About

Extracts a distance matrix from a phylogeny (parallel, low-memory)

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages