#!/usr/bin/env python3
"""Recompute the calculated numbers of the paper (Draft 5, 2026-11-08) from the raw data files beside it.

Run from the site folder:  python3 -I reproduce/reproduce.py          (text report)
                           python3 -I reproduce/reproduce.py --json   (machine-readable)
Standard library only. Deterministic: no random numbers, no system time, no network. Two runs give identical output.
Inputs: data/experiments-2/E5-chsh.csv (the four values of S), data/experiments-2/E6-sheet.csv (the neutron period).
Distances are in units of the quoted uncertainty, as in the paper's Data availability section; the visibility each S
implies is S / 2 sqrt 2 (paper, C1).
"""
import csv, json, math, os, sys

HERE = os.path.dirname(os.path.abspath(__file__))
DATA = os.path.join(os.path.dirname(HERE), "data")


def rows(folder, name):
    with open(os.path.join(DATA, folder, name + ".csv"), newline="", encoding="utf-8") as f:
        return [r for r in csv.DictReader(f) if r.get("pooled", "yes") == "yes"]


def experiments2():
    out = {}
    # E5: the four reported values of S against 2 (any value fixed in advance) and 2 sqrt 2 (largest quantum value)
    r = rows("experiments-2", "E5-chsh"); y = [float(x["value"]) for x in r]; s = [float(x["sigma"]) for x in r]
    d = [round((yi - 2) / si, 1) for yi, si in zip(y, s)]
    out["E5"] = {"values": y, "sigma": s, "quoted": [[x["value"], x["sigma"]] for x in r], "sigma_above_2": d,
                 "visibility": [round(yi / (2 * math.sqrt(2)), 3) for yi in y],
                 "tests": [{"label": "S at most 2 (each end reads a value fixed in advance, under locality and setting independence)",
                            "residuals": d, "result": "contradicted" if all(x > 0 for x in d) else "agrees"}],
                 "bound": {"label": "every central value below 2 sqrt 2",
                           "result": "agrees" if all(yi < 2 * math.sqrt(2) for yi in y) else "contradicted"}}
    # E6: the neutron interference period against 720 and 360 degrees
    r = rows("experiments-2", "E6-sheet"); v, sv = float(r[0]["value"]), float(r[0]["sigma"])
    out["E6"] = {"value": v, "sigma": sv, "quoted": [r[0]["value"], r[0]["sigma"]],
                 "tests": [{"label": "period 720 degrees", "residuals": [round((v - 720) / sv, 2)],
                            "result": "agrees" if abs(v - 720) <= 2 * sv else "contradicted"},
                           {"label": "period 360 degrees", "residuals": [round((v - 360) / sv, 1)],
                            "result": "agrees" if abs(v - 360) <= 2 * sv else "contradicted"}]}
    return out


def main():
    out = {"experiments_2": experiments2()}
    if "--json" in sys.argv:
        print(json.dumps(out, indent=1, sort_keys=True))
        return
    e5, e6 = out["experiments_2"]["E5"], out["experiments_2"]["E6"]
    print("REPRODUCE: the calculated numbers of the paper (Draft 5, 2026-11-08), from data/")
    for (yi, si), di in zip(e5["quoted"], e5["sigma_above_2"]):
        print("E5  (%s - 2) / %s = %.1f" % (yi, si, di))
    print("E5  %s -> %s" % (e5["tests"][0]["label"], e5["tests"][0]["result"]))
    print("E5  bound %s -> %s" % (e5["bound"]["label"], e5["bound"]["result"]))
    for (yi, _), vi in zip(e5["quoted"], e5["visibility"]):
        print("C1  visibility %s / 2 sqrt 2 = %.3f" % (yi, vi))
    t720, t360 = e6["tests"]
    print("E6  (720 - %s) / %s = %.2f; %s -> %s" % (*e6["quoted"], -t720["residuals"][0], t720["label"], t720["result"]))
    print("E6  (%s - 360) / %s = %.1f; %s -> %s" % (*e6["quoted"], t360["residuals"][0], t360["label"], t360["result"]))


if __name__ == "__main__":
    main()
