"""Single entry point for the timing study. Regenerates every table, number and figure. python3 code/run_all.py (about 5 minutes, single-threaded, peak memory about 2 GB) Steps 0. write data/events.csv (hand-compiled, cited table of dated events) 1. download the Moody et al. (2024) time-tree archive from Zenodo (227 MB, cached in fermi_raw/timing/) and extract LUCA node ages -> data/moody_node_ages.csv 2. analyses 1-5 -> data/*.csv and data/results.json 3. figures -> figures/*.png 4. print the key numbers (code/summary.py) """ from __future__ import annotations import json import os import sys import time import numpy as np import pandas as pd HERE = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, HERE) import config as cfg # noqa: E402 np.seterr(all="ignore") def jsonable(o): if isinstance(o, dict): return {str(k): jsonable(v) for k, v in o.items()} if isinstance(o, (list, tuple)): return [jsonable(v) for v in o] if isinstance(o, np.ndarray): return jsonable(o.tolist()) if isinstance(o, (np.floating, float)): return None if not np.isfinite(o) else float(o) if isinstance(o, (np.integer,)): return int(o) if isinstance(o, (np.bool_,)): return bool(o) return o def main(): t_start = time.time() import events_table import fetch_moody import a1_kipping import a2_hardsteps import a3_snyder_beattie import a4_models import a5_fbio import figures def stamp(msg): print(f"[{time.time() - t_start:6.1f} s] {msg}", flush=True) n = events_table.write_events_csv(os.path.join(cfg.DATA, "events.csv")) stamp(f"events table: {n} rows") nm = fetch_moody.main(os.path.join(cfg.DATA, "moody_node_ages.csv")) stamp(f"Moody et al. repository: {nm} node-age rows extracted" if nm else "Moody table: using cached copy") results = {"seed": cfg.SEED} # each analysis gets its own generator so that they can be rerun independently results["a1_kipping"] = a1_kipping.run(np.random.default_rng([cfg.SEED, 1])) stamp("analysis 1 (Kipping reproduction, plateau theorem, LUCA variants) done") results["a2_hardsteps"] = a2_hardsteps.run(np.random.default_rng([cfg.SEED, 2])) stamp("analysis 2 (hard steps) done") results["a3_snyder_beattie"] = a3_snyder_beattie.run(np.random.default_rng([cfg.SEED, 3])) stamp("analysis 3 (Snyder-Beattie et al. reproduction) done") results["a4_models"] = a4_models.run(np.random.default_rng([cfg.SEED, 4])) stamp("analysis 4 (hard steps vs pacing) done") out5, samples, curves = a5_fbio.run(np.random.default_rng([cfg.SEED, 5])) results["a5_fbio"] = out5 stamp("analysis 5 (f_bio) done") with open(os.path.join(cfg.DATA, "results.json"), "w") as f: json.dump(jsonable(results), f, indent=1) lam, tc = a1_kipping.theorem_curves() moody_tab = pd.read_csv(os.path.join(cfg.DATA, "a1_moody_luca_bf.csv")) figs = [figures.fig1_timeline(), figures.fig2_abiogenesis(lam, tc, moody_tab, results["a1_kipping"]["moody"]), figures.fig3_hardsteps(pd.read_csv(os.path.join(cfg.DATA, "a2_n_likelihoods.csv")), pd.read_csv(os.path.join(cfg.DATA, "a2_goodness_of_fit.csv"))), figures.fig4_snyder_beattie(pd.read_csv(os.path.join(cfg.DATA, "a3_table2_reproduction.csv"))), figures.fig5_fbio(samples, curves)] stamp("figures: " + ", ".join(os.path.basename(p) for p in figs)) print("results written to", os.path.join(cfg.DATA, "results.json")) import summary summary.main() if __name__ == "__main__": main()