Skip to main content

A Rust backed package to deal with phylogenetic trees

Project description

PhyloTree

license_badge crate version rust doc

This crate aims to be a general purpose package to deal with phylogenetic trees and simulate them. Is also comes with a simple CLI tool to manipulate and simulate phylogenetic trees directly from the command line.

Installing phylotree

Crate

To use this crate just run cargo add phylotree in your cargo project or add phylotree = "0.1.0" to your Cargo.toml file.

Cli

To install the CLI you can use cargo install phylotree

Or you can build the project from source:

git clone https://github.com/lucblassel/phylotree.git
cd phylotree
cargo build --release
mv target/release/phylotree <somewhere/in/your/PATH>

Using this crate

Below is some sample usage of the phylotree crate, please see docs.rs/phylotree for the full documentation.

use phylotree::tree::Tree;

//////////////////////////////////
// Building a tree from scratch //
//////////////////////////////////
let mut tree = Tree::new();

// Add the root node
let root = tree.add(Node::new());

// Add a child to the root
let child1 = tree.add_child(Node::new_named("Child_1"), root, None).unwrap();
// Add a child to the root with a branch length
let child2 = tree.add_child(Node::new_named("Child_2"), root, Some(0.5)).unwrap();

// Add more children
let child3 = tree.add_child(Node::new_named("Child_3"), child1, None).unwrap();

// Get depth of child
assert_eq!(tree.get(&child3).unwrap().get_depth(), 2)

///////////////////////////////
// Reading and writing trees //
///////////////////////////////
let newick_str = "((A:0.1,B:0.2)F:0.6,(C:0.3,D:0.4)E:0.5)G;";
let tree = Tree::from_newick(newick_str).unwrap();

assert_eq!(tree.to_newick().unwrap(), newick_string)

//////////////////////
// Traversing trees //
//////////////////////
let newick_str = "((A,B)C,(D,E)F)G;";
let mut tree = Tree::from_newick(newick_str).unwrap();
let root = tree.get_root().unwrap();

let preorder: Vec<_> = tree.preorder(&root).unwrap()
    .iter()
    .map(|node_id| tree.get(node_id).unwrap().name.clone().unwrap())
    .collect();

assert_eq!(preorder, vec!["G", "C", "A", "B", "F", "D", "E"]);


/////////////////////
// Comparing trees //
/////////////////////

// The second tree is just a random rotation of the first,
// they represent the same phylogeney
let newick_orig = "((A:0.1,B:0.2)F:0.6,(C:0.3,D:0.4)E:0.5)G;";
let newick_rota = "((D:0.3,C:0.4)E:0.5,(B:0.2,A:0.1)F:0.6)G;";

let tree_orig = Tree::from_newick(newick_orig).unwrap();
let tree_rota = Tree::from_newick(newick_rota).unwrap();

let rf = tree_orig.robinson_foulds(&tree_rota).unwrap();

assert_eq!(rf, 0)


/////////////////////////////////
// Computing a distance matrix //
/////////////////////////////////
let newick = "((T3:0.2,T1:0.2):0.3,(T2:0.4,T0:0.5):0.6);";
let tree = Tree::from_newick(newick).unwrap();
// Compute the whole distance matrix
let matrix = tree.distance_matrix_recursive().unwrap();
let phylip="\
4
T0    0  1.6  0.9  1.6
T1    1.6  0  1.5  0.4
T2    0.9  1.5  0  1.5
T3    1.6  0.4  1.5  0
";

assert_eq!(matrix.to_phylip(true).unwrap(), phylip)

Using the CLI

There is a simple CLI that comes with this package:

A simple command line tool to manipulate phylogenetic trees

Usage: phylotree <COMMAND>

Commands:
  generate     Generate random tree(s)
  stats        Get statistics about a tree
  compare      Compare two phylogenetic trees
  matrix       Output the phylogenetic distance matrix of the tree
  distance     Outputs a subset of phylogenetic distances
  collapse     Collapse branches that are under a certain branch length threshold
  remove       Remove tips from the trees
  deduplicate  Remove or collapse branches corresponding to identical sequences in a reference alignment
  help         Print this message or the help of the given subcommand(s)

Options:
  -h, --help  Print help

Python package

A python package has also been implemented, using PyO3 to create the python bindings. It is available on PyPi, you can see the API of the package here.

Example usage:

from phylotree import Tree

# Read a newick file
tree = Tree.from_newick("path/to/tree.nwk")

# Read a newick string
tree = Tree.from_string("((A,(C,E)D)B,((H)I)G)F;")

# Print newick formatted string of the tree
tree.to_newick()

# Get information about the tree
tree.n_nodes()
tree.n_tips()
tree.height()
tree.diameter()
tree.n_cherries()
tree.colless()
tree.sackin()
tree.is_binary
tree.is_rooted

# Get information about nodes
names = tree.get_leaf_names()
info = tree.get_node_attributes(name=names[0])
print(f"Parent edge has length: {info['parent_edge']}")
dist_branches, dist_topo = tree.get_distance(names=(names[0], names[1]))

distance_matrix = tree.to_matrix()
dist_mat = distance_matrix[(names[0], names[1])]
assert dist_branches == dist_mat

# Modify the tree
tree.compress() # Remove nodes with 1 parent and 1 child
tree.rescale() # Change branch lengths
tree.prune(name="D") # Remove sbutree rooted a specific node

# Traverse the tree in a given order
for node_id in tree.traversal(order="levelorder"):
    node = tree.get_node_attributes(id=node_id)
    print(node.name)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

phylotree-0.1.1.tar.gz (49.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

phylotree-0.1.1-cp311-cp311-manylinux_2_28_x86_64.whl (397.9 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

phylotree-0.1.1-cp311-cp311-macosx_13_0_arm64.whl (373.2 kB view details)

Uploaded CPython 3.11macOS 13.0+ ARM64

File details

Details for the file phylotree-0.1.1.tar.gz.

File metadata

  • Download URL: phylotree-0.1.1.tar.gz
  • Upload date:
  • Size: 49.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.4

File hashes

Hashes for phylotree-0.1.1.tar.gz
Algorithm Hash digest
SHA256 50a3d61800857573b643027ca69145598a7f867c7f42688a825411c2adb6237f
MD5 06222057400f3c0cd8135f05c43e486b
BLAKE2b-256 f49a807394a52e8c072d021eee3772ee1ec0025927d767ec3372f2edacc4bdfe

See more details on using hashes here.

File details

Details for the file phylotree-0.1.1-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for phylotree-0.1.1-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f1492734a97f7282cf27e7134f56744f31f85a1a186c58222bfdce3b7ac9e22f
MD5 ff5318f00ecdd11aaf40c568eb422512
BLAKE2b-256 9626e67015926da9e28018c1bff42b2fdbc8d4eeb275dc30d21057a5504d03de

See more details on using hashes here.

File details

Details for the file phylotree-0.1.1-cp311-cp311-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for phylotree-0.1.1-cp311-cp311-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 86bb558aa921163134bf082e8a336903a5105bd0b6635f26c29d64c505946634
MD5 db4ef68b747583ce27ec56cfd1c3b138
BLAKE2b-256 b29e055e95c5fba5315560b4396740a2e10711fa8e4624ee7baaecc1332b7089

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page