PhyNetPy
PhyNetPy is a Python library for phylogenetic network inference and analysis. It provides improved implementations of methods from PhyloNet, plus a framework for building new Bayesian and simulation-based methods.
Current version: v0.6.0 (see CHANGELOG.md for history).
Install
pip install phynetpy
PhyNetPy's graph core and likelihood kernels are compiled with Cython. Standard installation uses a published wheel when one is available; installing from the source distribution requires a C compiler:
pip install .
See Guides/INSTALLATION_GUIDE.md for virtual
environment and IDE setup.
Quick start
There are two things you can do with a phylogenetic network method -- find a
network, or evaluate one -- so there are two verbs, infer and score. What
they do is set by three independent arguments: the data you have, the
model of the biology, and the criterion you are optimising.
from phynetpy.infer import infer, score
from phynetpy.data import GeneTrees
from phynetpy.models import MSC
from phynetpy.criteria import MDC, Likelihood, PseudoLikelihood, Bayesian
gts = GeneTrees.from_file("gene_trees.nex", {"A": ["A1", "A2"], "B": ["B1"]})
result = infer(gts, model=MSC(), criterion=PseudoLikelihood())
print(result.best, result.score)
log_lik = score(result.best, gts, model=MSC(), criterion=Likelihood())
Switching methods means changing one argument, not learning a new command.
criterion=Bayesian() samples a posterior instead of maximising, and
result.posterior is then populated; everything else about the call is the
same. Strings work as shortcuts where an axis needs no parameters, so
infer(gts, criterion="MPL") is the same call.
Whether a combination is legal depends on all three axes, so dispatch goes
through a registry that doubles as a validity matrix. An impossible request
fails as a TypeError and an unimplemented one as a NotImplementedError; the
two are never confused. phynetpy.infer.validity_matrix() returns that table,
built from the registry itself, and registered_cells() lists every implemented
combination:
from phynetpy.infer import validity_matrix
for data, row in validity_matrix().items():
print(data, row)
GeneTrees {'MDC': '-', 'Likelihood': 'InferNetwork_ML', 'PseudoLikelihood': 'InferNetwork_MPL', 'Bayesian': 'MCMC_GT'}
Alignment {'MDC': 'x', 'Likelihood': '-', 'PseudoLikelihood': 'x', 'Bayesian': 'MCMC_SEQ'}
BiallelicMarkers {'MDC': 'x', 'Likelihood': 'MLE_BiMarkers', 'PseudoLikelihood': '-', 'Bayesian': 'MCMC_BiMarkers'}
A method name means implemented, - means legal but not yet implemented, and
x means the combination is not meaningful. The table above is for MSC; pass
a model class to tabulate another, such as validity_matrix(Allopolyploid).
Data structures, I/O, and analysis helpers live at the top level:
from phynetpy import read_newick, Network, Node, Edge, compare_networks
net = read_newick("(((A,B),C),D);")[0]
For the data structures and I/O, start with
examples/quickstart.py. For inference, start with
examples/mpl_demo.py (scoring) or
examples/search_flags_demo.py, which runs the
same data under two criteria side by side. Both finish in seconds.
examples/mcmc_gt_demo.py shows Bayesian search but
takes about nine minutes, since the full gene-tree likelihood is the expensive
objective.
Layout
| Path | What it holds |
|---|---|
src/ |
The phynetpy package. |
src/infer.py |
The public inference API: infer, score, simulate, result types, diagnostics. |
src/data/, src/models/, src/criteria/ |
The three axes those verbs dispatch on. |
src/_registry.py, src/_engines.py |
The validity matrix and one adapter per implemented cell. |
src/_*.py |
Method implementations. Private; reach them through phynetpy.infer. |
src/cython/ |
Required compiled graph core and likelihood/scoring kernels. |
examples/ |
Runnable end-to-end workflows. |
tests/ |
Test suite (pytest; -m "not slow" skips long MCMC recovery runs). |
docs/ |
Project site, plus the generated API reference in docs/api/. |
Guides/ |
Installation, I/O, and validation guides. |
scripts/ |
Benchmark and research tooling (not part of the library). |
Inference methods
Under the multispecies network coalescent, MSC(), each data-and-criterion
pair is one method. The PhyloNet command each corresponds to is named so the
literature stays findable; - marks a combination that is meaningful but not
implemented, and x one that is not defined at all.
MSC() |
MDC() |
Likelihood() |
PseudoLikelihood() |
Bayesian() |
|---|---|---|---|---|
GeneTrees |
- |
InferNetwork_ML |
InferNetwork_MPL |
MCMC_GT |
Alignment |
x |
- |
x |
MCMC_SEQ |
BiallelicMarkers |
x |
MLE_BiMarkers |
- |
MCMC_BiMarkers |
Allopolyploidy is a different model rather than a different command, so
maximum-parsimony allopolyploid inference (Hejase et al., PhyloNet's MPAllopp)
is infer(gts, model=Allopolyploid(), criterion=MDC()).
The references behind those cells: InferNetwork_ML (Yu et al., 2014),
InferNetwork_MPL (Yu & Nakhleh, 2015), MCMC_GT and MCMC_SEQ (Wen &
Nakhleh, 2018), MLE_BiMarkers and MCMC_BiMarkers (Bryant et al., 2012; Zhu
et al., 2018).
A third verb, simulate, runs the same axes backwards: it takes a model and a
network and returns a data-axis object, so a recovery check composes directly.
from phynetpy.infer import simulate
sim = simulate(MSC(theta=0.02), taxa=6, n=200) # draws its own species tree
recovered = infer(sim, criterion=PseudoLikelihood())
Development
python -m pytest -m "not slow" # test suite
python generate_docs.py # regenerate docs/api/
python deploy.py --dry-run --no-bump # test + build 0.6.0, no upload
The version lives in src/_version.py and is the single source of truth;
pyproject.toml reads it and phynetpy.__version__ re-exports it.
A tutorial and further instructions will be made available on our website, https://phylogenomics.rice.edu.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file phynetpy-0.6.0.tar.gz.
File metadata
- Download URL: phynetpy-0.6.0.tar.gz
- Upload date:
- Size: 465.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c8bba83ffdfa857410addd623a46086372be6aaa36b4f1f4069a0d134ce0d14c
|
|
| MD5 |
5cc950e831fd9e55726738e4b2695a88
|
|
| BLAKE2b-256 |
b0d3c8037c0899138fc183dada1e3b363fcf2a30cd94a061d96933d9a0faa243
|
File details
Details for the file phynetpy-0.6.0-cp314-cp314-win_amd64.whl.
File metadata
- Download URL: phynetpy-0.6.0-cp314-cp314-win_amd64.whl
- Upload date:
- Size: 670.0 kB
- Tags: CPython 3.14, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45959fa6969cb393d8f61b890954bbdf8b13eb77d3bdda41cc8eb6791863af8d
|
|
| MD5 |
a1b4e905dc81b3050f388b4d147824ef
|
|
| BLAKE2b-256 |
5075e162a63f77ec6fdf47b6f3d7236e69c1269f81412528a31dcc05a142b395
|