← Back to PhyNetPy

PhyNetPy Documentation

Library for the Development and Use of Phylogenetic Network Methods

BirthDeath Module v2.0.0

The BirthDeath module implements Yule (pure birth) and Constant Rate Birth-Death Process (CBDP) models for simulating phylogenetic networks with specified numbers of taxa or time horizons.

Author:
Mark Kessler
Last Edit:
11/10/25
Source:
BirthDeath.py

Exceptions

exception BirthDeathSimulationError(Exception)

Raised when something irrecoverably wrong happens during network generation within the Yule or CBDP algorithm.

Helper Functions

def estimate_expected_tips(gamma: float, time: float) -> float

Estimate the expected number of taxa produced by a Yule process.

Parameter Type Description
gamma float Birth rate parameter (must be > 0)
time float Target time horizon (must be >= 0)
Returns: float - Expected number of taxa at the provided time
def random_species_selection(nodes: list[Node], rng: np.random.Generator) -> Node

Returns a random live Node from a list. The node returned will be operated on during a birth or death event.

def live_species(nodes: list[Node]) -> list[Node]

Returns the subset of nodes that represent live lineages (have attribute "live" set to True).

Yule Class

class Yule

Pure birth model for simulating phylogenetic networks. Can condition on either a fixed number of extant taxa (n) or a time horizon.

Constructor

__init__(self, gamma: float, n: int = None, time: float = None, rng: np.random.Generator = None)

Create a Yule process simulator.

Parameter Type Description
gamma float Birth rate (must be > 0). Higher rates produce shorter branches.
n int Number of extant taxa at end of simulation (>= 2)
time float Alternative: age of the tree to simulate
rng np.random.Generator Random number generator for reproducibility
Raises: BirthDeathSimulationError - If parameters are invalid

Methods

set_gamma(self, new_gamma: float) -> None

Set the birth rate parameter.

set_taxa(self, value: int) -> None

Set the target number of taxa (>= 2).

set_time(self, value: float) -> None

Set the target tree age (> 0).

generate_network(self) -> Network

Simulate one network starting with 2 lineages and running speciation events until the goal is reached.

Returns: Network - The simulated tree
generate_networks(self, num_networks: int) -> list[Network]

Generate multiple networks under the same model parameters.

clear_generated(self) -> None

Clear the list of previously generated networks.

CBDP Class

class CBDP

Constant Rate Birth-Death Process for network simulation. Unlike Yule, this model includes extinction events, so networks may have more leaves than live lineages.

Constructor

__init__(self, gamma: float, mu: float, n: int, sample: float = 1)

Create a Constant Rate Birth-Death simulator.

Parameter Type Description
gamma float Birth rate (must be > mu)
mu float Death rate (must be >= 0 and < gamma)
n int Number of LIVE taxa in simulated network (>= 2)
sample float Sampling rate in (0, 1]. Default is 1.

Methods

set_bd(self, gamma: float, mu: float) -> None

Set the birth and death rate parameters.

set_n(self, new_n: int) -> None

Set the target number of live taxa.

set_sample(self, new_sampling: float) -> None

Set the sampling rate (must be in (0, 1]).

generate_network(self) -> Network

Simulate a single network under the CBDP model.

generate_networks(self, m: int) -> list[Network]

Generate m networks under the same model parameters.

Usage Examples

from PhyNetPy.BirthDeath import Yule, CBDP
import numpy as np

# Yule model - condition on number of taxa
yule = Yule(gamma=0.5, n=10)
tree = yule.generate_network()
print(f"Generated tree with {len(tree.get_leaves())} leaves")

# Yule model - condition on time
yule_time = Yule(gamma=0.5, time=5.0)
tree = yule_time.generate_network()

# Yule with reproducible RNG
rng = np.random.default_rng(seed=42)
yule_seeded = Yule(gamma=0.5, n=10, rng=rng)
trees = yule_seeded.generate_networks(100)

# Constant Rate Birth-Death Process
cbdp = CBDP(gamma=1.0, mu=0.3, n=10, sample=0.8)
tree = cbdp.generate_network()

# Live species vs total leaves
live = live_species(tree.V())
print(f"Live lineages: {len(live)}")
print(f"Total leaves: {len(tree.get_leaves())}")

See Also

Navigation

Modules

This Page