Files
obitools4/autodoc/docmd/pkg_obiphylo.md
T

62 lines
3.1 KiB
Markdown
Raw Normal View History

2026-04-07 08:36:50 +02:00
# `obiphylo` Package: Semantic Description
The `obiphylo` package provides a minimal yet expressive data structure and utilities for representing **phylogenetic trees** in Go, prioritizing simplicity, extensibility, and interoperability with standard phylogenetic formats.
## Core Type: `PhyloNode`
Represents a node in a phylogenetic tree—either an operational taxonomic unit (leaf) or an internal branching point.
### Public Fields
- `Name string`: Optional identifier for the node (e.g., species name, OTU label). May be empty.
- `Children map[*PhyloNode]float64`: Maps child nodes to their associated **branch lengths** (evolutionary distances). Supports `NaN` for unspecified or unmeasured branches.
- `Attributes map[string]any`: A flexible key-value store for arbitrary metadata (e.g., bootstrap values, posterior probabilities, geographic origin). Values may be of any type.
> ⚠️ *All fields are exported for direct read/write access, but users should prefer the provided methods to ensure consistency (e.g., `AddChild`, `SetAttribute`).*
## Public Methods
### Construction & Mutation
- **`NewPhyloNode(name string) *PhyloNode`**
Instantiates a new node with optional name. Initializes `Children` and `Attributes` as empty maps.
- **`AddChild(child *PhyloNode, distance float64)`**
Appends a child node to the current one with specified branch length. If `distance` is `NaN`, it is stored as-is (and omitted in Newick output).
*Enables incremental tree building from leaves to root.*
- **`SetAttribute(key string, value any)`**
Stores or updates a metadata entry on the node. Overwrites existing keys.
- **`GetAttribute(key string) (any, bool)`**
Retrieves a metadata value and reports presence via boolean. Returns zero `value` if key absent.
### Tree Serialization
- **`Newick(level int) string`**
Recursively generates a Newick-formatted subtree rooted at the current node.
- Nodes without children appear as `Name` (or empty string if unnamed).
- Internal nodes are rendered with comma-separated children in parentheses.
- Branch lengths (`:distance`) appear *only if finite* (i.e., `!math.IsNaN(distance)`).
- Indentation (`level * "\t"`) improves human readability.
- Root-level calls (e.g., `root.Newick(0)`) append a final semicolon (`;`).
*Designed for export to tools like RAxML, FigTree, or Iq-TREE.*
## Design Principles
- **Zero external dependencies**: Pure Go implementation.
- **Idiomatic efficiency**: Child lookup via `map` ensures O(1) average access.
- **Extensibility over rigidity**: Arbitrary metadata via `any` supports evolving annotation needs without API changes.
- **Format compliance**: Newick output adheres to widely accepted syntax (with optional branch lengths), enabling seamless integration with phylogenetic software ecosystems.
## Usage Example
```go
root := obiphylo.NewPhyloNode("Root")
leafA := obiphylo.NewPhyloNode("Species_A")
leafB := obiphylo.NewPhyloNode("Species_B")
root.AddChild(leafA, 1.2)
root.AddChild(leafB, math.NaN()) // distance omitted in output
leafA.SetAttribute("bootstrap", 95)
root.Newick(0) // → "\t(Species_A:1.2,Species_B);"
```