96 lines
3.1 KiB
Python
96 lines
3.1 KiB
Python
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
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_extinction as ext
|
|
import renunney.track1_reference as ref
|
|
|
|
|
|
def _sample_summaries():
|
|
return [
|
|
ref.GenerationSummary(
|
|
t=0,
|
|
N=10,
|
|
female_fraction=0.5,
|
|
male_count=5,
|
|
female_count=5,
|
|
fecundity=3.0,
|
|
mean_fitness=0.8,
|
|
mean_expected_female_productivity=2.4,
|
|
target_value=0.0,
|
|
mean_allele_value=0.2,
|
|
mean_genotype_value=0.2,
|
|
mean_tracking_gap=0.2,
|
|
paper_M=0.05,
|
|
expected_mutations_current_N=0.1,
|
|
realized_mutation_count=0,
|
|
realized_mutation_rate_per_allele=0.0,
|
|
birth_count=6,
|
|
surviving_offspring_count=4,
|
|
ne_approx=5.0,
|
|
extinct=False,
|
|
),
|
|
ref.GenerationSummary(
|
|
t=1,
|
|
N=0,
|
|
female_fraction=0.0,
|
|
male_count=0,
|
|
female_count=0,
|
|
fecundity=0.0,
|
|
mean_fitness=0.0,
|
|
mean_expected_female_productivity=0.0,
|
|
target_value=0.1,
|
|
mean_allele_value=0.0,
|
|
mean_genotype_value=0.0,
|
|
mean_tracking_gap=-0.1,
|
|
paper_M=0.05,
|
|
expected_mutations_current_N=0.0,
|
|
realized_mutation_count=0,
|
|
realized_mutation_rate_per_allele=0.0,
|
|
birth_count=0,
|
|
surviving_offspring_count=0,
|
|
ne_approx=0.0,
|
|
extinct=True,
|
|
),
|
|
]
|
|
|
|
|
|
def test_build_extinction_generation_rows_derives_expected_fields():
|
|
params = ref.Track1Parameters(K=5000, N0=20, n=1, u=5e-6, R=10.0, T=20)
|
|
rows = ext.build_extinction_generation_rows(params, _sample_summaries(), seed=7)
|
|
assert len(rows) == 2
|
|
assert rows[0].M == 0.05
|
|
assert rows[0].survival_fraction == 4 / 6
|
|
assert rows[0].replacement_deficit == 0.0
|
|
assert rows[0].mutation_shortfall == 0.1
|
|
assert rows[0].extinction_next_step is True
|
|
assert rows[1].extinction_occurred is True
|
|
|
|
|
|
def test_build_extinction_run_row_summarizes_extinction_and_mutation_streaks():
|
|
params = ref.Track1Parameters(K=5000, N0=20, n=1, u=5e-6, R=10.0, T=20)
|
|
row = ext.build_extinction_run_row(params, _sample_summaries(), seed=7)
|
|
assert row.extinction_occurred is True
|
|
assert row.first_extinction_t == 1
|
|
assert row.first_productivity_below_replacement_t == 1
|
|
assert row.longest_zero_mutation_streak == 2
|
|
assert row.cumulative_expected_mutations == 0.1
|
|
assert row.cumulative_realized_mutations == 0
|
|
|
|
|
|
def test_save_jsonl_writes_row_data(tmp_path: Path):
|
|
params = ref.Track1Parameters(K=5000, N0=20, n=1, u=5e-6, R=10.0, T=20)
|
|
row = ext.build_extinction_run_row(params, _sample_summaries(), seed=7)
|
|
path = tmp_path / "runs.jsonl"
|
|
ext.save_jsonl([row], path)
|
|
lines = path.read_text(encoding="utf-8").splitlines()
|
|
assert len(lines) == 1
|
|
parsed = json.loads(lines[0])
|
|
assert parsed["seed"] == 7
|
|
assert parsed["extinction_occurred"] is True
|