agentsclimarketplace

Tree io

Skill FridrichMethod/awesome-skills/skills/tree-io

Read, write, and convert phylogenetic tree files with Biopython Bio.Phylo, and choose an annotation-preserving parser (treeio, DendroPy) when metadata matters. Covers why a tree file is a lossy serialization, why format conversion silently drops BEAST/MrBayes node annotations (posteriors, HPD intervals, rates), the Newick support-vs-label ambiguity that mislabels bootstrap values, and the Nexus TRANSLATE and rooted/unrooted traps. Use when parsing Newick, Nexus, NHX, phyloXML, or NeXML, converting between formats, handling posterior tree sets, or moving annotated BEAST trees without losing the credible intervals. Routes annotation-critical reads to DendroPy or treeio and orthology/alignment context to sibling skills.From its SKILL.md

Install
npx -y skills add FridrichMethod/awesome-skills --skill tree-io

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 13 stars13 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

14.3 KB, ~3.6k tokens by cl100k_base, as published. Nobody here has run it

Version Compatibility

Reference examples tested with: BioPython 1.83+. Annotation-preserving alternatives: DendroPy 5+ (Python), treeio 1.26+ / ape 5.8+ (R).

Before using code patterns, verify installed versions match. If versions differ:

  • Python: pip show biopython then help(module.function) to check signatures
  • R: packageVersion('treeio') then ?read.beast to verify parameters

If code throws ImportError, AttributeError, or TypeError, introspect the installed package and adapt the example to match the actual API rather than retrying.

Bio.Phylo stores a Newick [&...] bracket as opaque .comment text and does NOT parse BEAST key-values; DendroPy extract_comment_metadata=True and treeio read.beast do.

Tree I/O -- A Tree File Is a Lossy Serialization

"Read and convert my tree files" -> Parse a tree into an in-memory object and re-serialize it, knowing which annotations each format and parser preserves.

  • Python: Phylo.read('tree.nwk', 'newick'), Phylo.convert(...) (Bio.Phylo)
  • Annotation-critical: dendropy.Tree.get(..., extract_comment_metadata=True) or treeio read.beast()

Scope: reading, writing, converting, and inspecting tree files, and selecting a parser that keeps the annotations the analysis needs. Rooting, pruning, collapsing -> tree-manipulation. Plotting and mapping annotations onto branches -> tree-visualization. Producing BEAST/MrBayes annotated trees -> bayesian-inference, divergence-dating. Taxon-name sanitization shares the whitespace traps in sequence-io/read-sequences.

The Single Most Important Modern Insight

A tree file is a lossy serialization of a richer in-memory object. The biologist cares about the topology plus its annotations -- branch supports, posterior probabilities, 95% HPD intervals on node heights, per-branch rates, divergence dates, taxon metadata -- and formats differ enormously in which of these they can hold, while parsers differ in which they actually read back. Three load-bearing facts:

  1. Conversion is a silent data-destroying operation. Reading a BEAST MCC tree and writing plain Newick produces a topologically identical tree that plots fine, but the HPD intervals, clade posteriors, and per-branch rates are gone and unrecoverable without re-running a multi-day MCMC. The loss is invisible until a reviewer asks where the credible intervals went.
  2. The tool, not the format string, decides whether [&...] metadata survives. In Python the naive default (Bio.Phylo) drops BEAST key-values; in R the naive default (ape::read.nexus) drops them; the tools built to preserve them are DendroPy (extract_comment_metadata=True) and treeio (read.beast). Route annotated trees through those.
  3. In plain Newick a bare number has no fixed meaning. In (A,B)95:0.3 the 95 could be a bootstrap, a posterior, an internal clade name, or a second branch length. Only the tool that wrote the file knows; a parser that guesses wrong turns supports into names silently. IQ-TREE overloads the slot further, writing SH-aLRT/UFBoot (e.g. 87.5/98), which a single-value parser truncates or chokes on.

Tool Taxonomy

Tool (lang)BEAST [&...]NHXphyloXML richnessWhen
treeio (R)YES, structured (read.beast/read.mrbayes/read.iqtree)YESvia tidytree/ggtreethe default whenever annotations matter; feeds ggtree
DendroPy (Py)YES, structured (.annotations)YESnoPython work needing metadata, posterior sets, tree distances, conversion with annotations
ETE3/ETE4 (Py)partial (custom features)YES, nativenoreconciliation, NHX round-trips, programmatic node features
Bio.Phylo (Py)NO key-value parse (opaque .comment)noYES, richestgeneral pipelines, conversion among its 5 formats, phyloXML annotation
ape (R)NO (drops [&...])nonofast topology/branch-length analysis; pair with treeio for annotated files

References: Bio.Phylo Talevich 2012; DendroPy Sukumaran 2010; ETE3 Huerta-Cepas 2016; ape Paradis 2019; treeio Wang 2020.

One-line decision rule: if the file came from BEAST, MrBayes, or RevBayes or carries [&...]/&&NHX that matters, read it with treeio (R) or DendroPy (Py); otherwise Bio.Phylo (Py) or ape (R) is fine. Never route a BEAST MCC tree through Bio.Phylo or ape::read.nexus when the HPDs are needed.

Format Capability (What Each Format Can Hold)

CapabilityNewickNHXNexus (BEAST-annotated)phyloXMLNeXML
Topology + branch lengthsyesyesyesyesyes
One support valueambiguous slotB= tagcomment keytyped <confidence>typed meta
Multiple supports per nodeno (single slot)tagscomment keysyes (n elements)yes
Posterior / HPD intervalsnonoyes (_95%_HPD={})via propertyvia meta
Per-branch rates / datesnotagsyesyesyes
Taxonomy (NCBI id/rank)noS=/T=noyes, typedyes
Schema-validatednonolooseyes (XSD)yes (XSD)

Newick/NHX are compact and grep-able; phyloXML/NeXML are verbose XML (often 5-20x larger) but typed and validatable -- prefer XML for archiving/exchange where machine-checkable semantics matter, Newick/Nexus for pipeline interchange. BEAST/FigTree metadata rides inside a Nexus (or Newick) [&...] comment, so "it is a Nexus file" says nothing about whether annotations survive -- only the parser does.

Reading, Writing, and Converting (Bio.Phylo)

Goal: Move trees between formats and inspect them without assuming a single tree or losing annotations.

Approach: Use Phylo.read for exactly one tree and Phylo.parse for many (posterior sets); use Phylo.convert only among formats of equal or greater capability; check .confidence vs .name to confirm support was read into the right slot.

from Bio import Phylo

tree = Phylo.read('tree.nwk', 'newick')          # exactly one tree; raises if 0 or >1
posterior = list(Phylo.parse('run.trees', 'nexus'))   # many trees: posterior/bootstrap set
Phylo.write(tree, 'tree.xml', 'phyloxml')        # phyloXML is Bio.Phylo's richest format

Phylo.convert('tree.nex', 'nexus', 'tree.nwk', 'newick')   # WARNING: Newick cannot hold [&...]; annotations dropped

for clade in tree.get_nonterminals():
    print(clade.confidence, clade.name)          # confirm the support landed in .confidence, not .name

Supported format strings: newick, nexus, phyloxml, nexml, cdao. Colors and branch widths persist only in phyloXML.

Preserve BEAST/MrBayes Annotations Before Down-Converting

Goal: Keep posteriors, HPD intervals, and rates when a downstream tool wants plain Newick.

Approach: Read with an annotation-aware parser, extract the numbers into a side table that travels with the analysis, and only then write a stripped topology -- never down-convert first.

import dendropy

tree = dendropy.Tree.get(path='mcc.tree', schema='nexus', extract_comment_metadata=True)
for node in tree:
    if node.annotations.get_value('posterior') is not None:
        post = node.annotations.get_value('posterior')
        hpd = node.annotations.get_value('height_95%_HPD')   # raw BEAST key; treeio typically exposes it as height_0.95_HPD (exact name varies by source program and version -- introspect the columns)
        # persist post/hpd to a side table keyed by the clade before any conversion
tree.write(path='topology.nwk', schema='newick', suppress_annotations=True)   # intentional, after extraction

In R the equivalent is treeio read.beast('mcc.tree') then get.data() / as_tibble(), feeding ggtree (tree-visualization); write.beast() re-serializes with annotations intact.

Per-Method Failure Modes

BEAST/MrBayes MCC to Plain Newick Erases the Credible Intervals

Trigger: Phylo.convert, ape::read.nexus + write.tree, or any "just give me the topology" step on an annotated tree. Mechanism: The HPDs, posteriors, and rates live only in the [&...] comments, which plain Newick cannot hold and stripping parsers discard. Symptom: The output plots fine but the credible intervals are gone, irrecoverable without re-running the MCMC. Fix: Read with treeio read.beast or DendroPy extract_comment_metadata=True; extract the numbers to a side table; keep the original .tree as the source of truth.

Support Value Read as a Node Name (or Truncated)

Trigger: Parsing a tree whose internal-node slot holds a bootstrap, a posterior, a clade name, or IQ-TREE's SH-aLRT/UFBoot dual value. Mechanism: The Newick grammar gives one slot for all of these; the parser must be told which it is, and a single-value reader truncates the /-delimited dual support. Symptom: Supports appear as .name strings, or only one of two IQ-TREE values survives, or the parse errors on /. Fix: Know what wrote the file; in Bio.Phylo inspect .confidence vs .name; in treeio use read.iqtree/read.raxml, which split dual support correctly.

Whitespace, Underscore, or Non-ASCII Taxon Names

Trigger: Tip names with spaces, parentheses, commas, or accented characters; reliance on the Newick underscore-space convention. Mechanism: Naive CLI tools split unquoted spaces, and underscore-to-space auto-conversion silently desyncs tip labels from a metadata join key. Symptom: Downstream tools error or a metadata merge matches nothing. Fix: Sanitize to [A-Za-z0-9_.], single-quote when spaces are unavoidable, and round-trip-test the labels against the metadata table before any join.

Nexus TRANSLATE-Table Desync and Rooted/Unrooted Confusion

Trigger: Hand-editing or merging Nexus tree blocks; assuming topology shape implies rootedness. Mechanism: The integer-to-name TRANSLATE map can decouple from the tree and silently relabel tips; Newick does not flag rootedness (a basal trifurcation conventionally signals unrooted, but tools disagree), while Nexus carries an explicit [&R]/[&U]. Symptom: Tips are mislabeled after a merge, or a rooting-sensitive analysis runs on the wrong assumption without erroring. Fix: Parse with a translate-aware reader (treeio/DendroPy/ape apply it); verify tip-label sets match across merged trees; set rootedness explicitly rather than trusting topology shape.

Quantitative and Practical Notes

ItemGuidanceWhy
Support-value scalesbootstrap/UFBoot in [0,100], posterior in [0,1], SH-aLRT in [0,100]a number is meaningless without knowing which test produced it; preserve provenance, not just the value
Multi-tree filesuse Phylo.parse / DendroPy TreeList / treeio read.beast; check object lengtha single-tree reader on a .trees posterior returns only the first or errors
Round-trip testread -> write -> read and diff the annotations, not just the topologytopology almost always survives and gives false confidence
Posterior set vs MCC.trees is the full posterior; .tree/.mcc is the single annotated summaryread.beast on a full posterior is huge; usually the MCC is wanted

Common Errors

Error / symptomCauseSolution
HPD bars missing after conversionconverted a BEAST tree to Newickextract annotations with treeio/DendroPy first
Phylo.read raises on a .trees filemultiple trees in the fileuse Phylo.parse and iterate
Bootstrap values show up as taxon namesnode-label slot read as .nameset/inspect confidence parsing; use a software-specific reader
Metadata join matches nothingunderscore/space relabeling of tipssanitize and round-trip-test labels before joining
Parser errors on [strict parser chokes on FigTree commentstrip comments only after extracting needed metadata

References

Cock PJA, Antao T, Chang JT, et al. 2009. Biopython: freely available Python tools for computational molecular biology and bioinformatics. Bioinformatics 25(11):1422-1423. Talevich E, Invergo BM, Cock PJA, Chapman BA. 2012. Bio.Phylo: a unified toolkit for processing, analyzing and visualizing phylogenetic trees in Biopython. BMC Bioinformatics 13:209. Sukumaran J, Holder MT. 2010. DendroPy: a Python library for phylogenetic computing. Bioinformatics 26(12):1569-1571. Huerta-Cepas J, Serra F, Bork P. 2016. ETE 3: reconstruction, analysis, and visualization of phylogenomic data. Molecular Biology and Evolution 33(6):1635-1638. Paradis E, Schliep K. 2019. ape 5.0: an environment for modern phylogenetics and evolutionary analyses in R. Bioinformatics 35(3):526-528. Wang L-G, Lam TT-Y, Xu S, et al. 2020. Treeio: an R package for phylogenetic tree input and output with richly annotated and associated data. Molecular Biology and Evolution 37(2):599-603. Maddison DR, Swofford DL, Maddison WP. 1997. NEXUS: an extensible file format for systematic information. Systematic Biology 46(4):590-621. Han MV, Zmasek CM. 2009. phyloXML: XML for evolutionary biology and comparative genomics. BMC Bioinformatics 10:356. Vos RA, Balhoff JP, Caravas JA, et al. 2012. NeXML: rich, extensible, and verifiable representation of comparative data and metadata. Systematic Biology 61(4):675-689.

Related Skills

  • tree-manipulation - rooting, pruning, and collapsing where rooted/unrooted and polytomy choices bite
  • tree-visualization - ggtree and ETE consume the annotations preserved here
  • bayesian-inference - produces the BEAST/MrBayes annotated trees whose metadata must survive
  • divergence-dating - produces MCC trees with HPD intervals on node ages
  • sequence-io/read-sequences - taxon-name sanitization shares the whitespace and non-ASCII traps

What ships with it: 4 files

6.1 KB alongside SKILL.md, 3 of them executable

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.