ReNunney/tests/test_track1_dynamics.py

96 lines
3.6 KiB
Python

import sys
from pathlib import Path
import numpy as np
ROOT = Path(__file__).resolve().parents[1]
SRC_DIR = ROOT / "src"
if str(SRC_DIR) not in sys.path:
sys.path.insert(0, str(SRC_DIR))
import renunney.track1_reference as ref
def test_zero_mutation_preserves_zero_alleles_in_one_generation():
params = ref.Track1Parameters(K=5000, N0=2, n=2, u=0.0, R=10.0, T=20)
state = ref.PopulationState(
genomes=np.zeros((2, 2, 2), dtype=np.int16),
sexes=np.array([0, 1], dtype=np.int8),
)
next_state, summary = ref.simulate_one_generation(state, params, t=0, rng=np.random.default_rng(1))
assert summary.mean_allele_value == 0.0
assert int(next_state.genomes.sum()) == 0
def test_zero_offspring_fitness_prevents_survival(monkeypatch):
params = ref.Track1Parameters(K=5000, N0=2, n=1, u=0.0, R=10.0, T=20)
state = ref.PopulationState(
genomes=np.zeros((2, 2, 1), dtype=np.int16),
sexes=np.array([0, 1], dtype=np.int8),
)
def fake_fitness(genomes, r, T, t):
if genomes.shape[0] == 1:
return np.zeros(1, dtype=float)
return np.ones(genomes.shape[0], dtype=float)
monkeypatch.setattr(ref, "genotype_fitness", fake_fitness)
monkeypatch.setattr(ref, "female_fecundity", lambda r, N, K: 4.0)
monkeypatch.setattr(ref, "realize_birth_counts", lambda fecundity, sexes, rng: np.array([3, 0], dtype=np.int32))
next_state, _ = ref.simulate_one_generation(state, params, t=0, rng=np.random.default_rng(2))
assert next_state.size == 0
def test_unit_offspring_fitness_keeps_all_births(monkeypatch):
params = ref.Track1Parameters(K=5000, N0=2, n=1, u=0.0, R=10.0, T=20)
state = ref.PopulationState(
genomes=np.zeros((2, 2, 1), dtype=np.int16),
sexes=np.array([0, 1], dtype=np.int8),
)
monkeypatch.setattr(ref, "genotype_fitness", lambda genomes, r, T, t: np.ones(genomes.shape[0], dtype=float))
monkeypatch.setattr(ref, "female_fecundity", lambda r, N, K: 4.0)
monkeypatch.setattr(ref, "realize_birth_counts", lambda fecundity, sexes, rng: np.array([3, 0], dtype=np.int32))
next_state, summary = ref.simulate_one_generation(state, params, t=0, rng=np.random.default_rng(2))
assert summary.female_count == 1
assert next_state.size == 3
def test_one_father_is_used_per_female_reproductive_event(monkeypatch):
params = ref.Track1Parameters(K=5000, N0=3, n=2, u=0.0, R=10.0, T=20)
state = ref.PopulationState(
genomes=np.array(
[
[[0, 0], [0, 0]],
[[1, 1], [1, 1]],
[[2, 2], [2, 2]],
],
dtype=np.int16,
),
sexes=np.array([0, 1, 1], dtype=np.int8),
)
monkeypatch.setattr(ref, "genotype_fitness", lambda genomes, r, T, t: np.ones(genomes.shape[0], dtype=float))
monkeypatch.setattr(ref, "female_fecundity", lambda r, N, K: 4.0)
monkeypatch.setattr(ref, "realize_birth_counts", lambda fecundity, sexes, rng: np.array([3, 0, 0], dtype=np.int32))
next_state, _ = ref.simulate_one_generation(state, params, t=0, rng=np.random.default_rng(3))
paternal_alleles = next_state.genomes[:, 1, :]
assert next_state.size == 3
assert np.unique(paternal_alleles).size == 1
def test_absence_of_males_or_females_counts_as_extinction():
female_only = ref.PopulationState(
genomes=np.zeros((2, 2, 1), dtype=np.int16),
sexes=np.array([0, 0], dtype=np.int8),
)
male_only = ref.PopulationState(
genomes=np.zeros((2, 2, 1), dtype=np.int16),
sexes=np.array([1, 1], dtype=np.int8),
)
assert ref.is_extinct(female_only) is True
assert ref.is_extinct(male_only) is True