""" Single entry point for the study "second_origin_search": regenerates every number, table and figure. python3 run_all.py # uses cached raw downloads when present (a few minutes) python3 run_all.py --refresh # re-downloads every public count (MGnify pages take about 40 minutes; the counts will have grown) python3 run_all.py --skip-model # reuse ../data/model_samples*.npz instead of re-running Model 4.1 Steps 1 fetch_public_counts.py MGnify, GTDB, NCBI, ENA, PRIDE, MetaboLights counts and MGnify per-analysis summaries -> ../data/db_counts.csv ... 2 fetch_pubmed_counts.py PubMed record counts by method class, plus union queries that count each record once -> ../data/pubmed_method_counts.csv 3 earth_stats.py unassigned share of sequence by biome (with study counts, reweighting and pooled share), least-annotated studies, genome catalogue -> ../data/earth_*.csv/json 4 model_samples.py copies models/model4.py to scratch (never modified) and runs it, 60,000 samples per run, under nice -n 10 5 completeness.py itemised completeness from ../data/completeness_factors.csv (the only hand-authored input: 76 rows of structured judgement, none of them a measurement) and the null likelihood under three structures (per habitat; per origin for persistence; per origin for every factor = the model's own functional form) 6 update.py re-weights the model's samples by the likelihood of the record under each structure; scores the Cheyava Falls potential biosignature over a range of likelihood ratios and finds the break-even; forecasts, claims, independence 7 figures.py the five figures Revision after referee review (2026-10-12): see the "Response to referee" section of report.md for what changed and why. Raw downloads go to $SOS_RAW (default fermi_raw/second_origin_search). Nothing outside this study directory is written, except the scratch copy of the model under $SOS_RAW/model_copy. """ import os import subprocess import sys import time HERE = os.path.dirname(os.path.abspath(__file__)) REFRESH = ["--refresh"] if "--refresh" in sys.argv else [] SKIP_MODEL = "--skip-model" in sys.argv STEPS = [ (["fetch_public_counts.py"] + REFRESH, False), (["fetch_pubmed_counts.py"] + REFRESH, False), (["earth_stats.py"], False), (["model_samples.py", "60000"], True), (["completeness.py"], False), (["update.py"], False), (["figures.py"], False), ] def main(): t00 = time.time() for args, nice in STEPS: if SKIP_MODEL and args[0] == "model_samples.py": print("== skipping model_samples.py (--skip-model)"); continue cmd = (["nice", "-n", "10"] if nice else []) + [sys.executable, os.path.join(HERE, args[0])] + args[1:] print("==", " ".join(cmd), flush=True) t0 = time.time() subprocess.run(cmd, check=True, cwd=HERE, env=dict(os.environ, OMP_NUM_THREADS="1", OPENBLAS_NUM_THREADS="1", MKL_NUM_THREADS="1")) print(f"== done in {time.time() - t0:.0f} s", flush=True) print(f"all steps finished in {time.time() - t00:.0f} s") if __name__ == "__main__": main()