"""Registered scorer (protocol-births.json). Usage:
  births_score.py <train w2017.csv> <test w2022.csv> <voice-2022.jsonl> > results-births.json
AUC of the voice and of age alone (logistic in age and its square, fitted on NSFG 2017-2019) on NSFG
2022-2023, with a bootstrap interval of the difference; and the level: the voice's mean probability
carried by the national general fertility rate (GFR_RATIO) against the observed share and its 95%
interval. The regression on all facts is reported beside them."""
import sys, json, hashlib, numpy as np, pandas as pd
GFR_RATIO = 0.917  # NCHS general fertility rate, window years of 2022-2023 over those of 2017-2019 (protocol)
args = sys.argv[1:]; sys.argv = [sys.argv[0], args[0]]
exec(open(__file__.replace("births_score.py", "births_dev.py")).read().split("idx = rng.permutation")[0])  # design, fit, auc
tr, te = pd.read_csv(args[0], index_col=0), pd.read_csv(args[1], index_col=0)
v = {json.loads(l)["caseid"]: json.loads(l)["p"] for l in open(args[2])}
y = te.birth.to_numpy(); sv = np.array([v[i] for i in te.index])
pa = 1 / (1 + np.exp(-design(te, False) @ fit(design(tr, False), tr.birth.to_numpy())))
pf = 1 / (1 + np.exp(-design(te, True) @ fit(design(tr, True), tr.birth.to_numpy())))
rng = np.random.default_rng(20261010); B = [rng.integers(0, len(y), len(y)) for _ in range(2000)]
ci = lambda a, b: [round(float(x), 4) for x in np.quantile([auc(a[i], y[i]) - auc(b[i], y[i]) for i in B], [.025, .975])]
oci = [round(float(x), 4) for x in np.quantile([y[i].mean() for i in B], [.025, .975])]
carried = float(sv.mean() * GFR_RATIO)
res = {"protocolSha256": hashlib.sha256(open(__file__.replace("births_score.py", "protocol-births.json"), "rb").read()).hexdigest(),
       "women": int(len(y)), "births": int(y.sum()),
       "auc": {"voice": round(auc(sv, y), 4), "age": round(auc(pa, y), 4), "facts": round(auc(pf, y), 4)},
       "voiceMinusAge95": ci(sv, pa), "voiceMinusFacts95": ci(sv, pf), "factsMinusAge95": ci(pf, pa),
       "level": {"observed": round(float(y.mean()), 4), "observed95": oci, "voiceMean": round(float(sv.mean()), 4), "voiceCarried": round(carried, 4),
                 "ageCarried": round(float(pa.mean() * GFR_RATIO), 4), "factsCarried": round(float(pf.mean() * GFR_RATIO), 4)}}
res["beatsAge"] = bool(res["voiceMinusAge95"][0] > 0)
res["levelInside"] = bool(oci[0] <= carried <= oci[1])
res["primary_met"] = res["beatsAge"] and res["levelInside"]
print(json.dumps(res, indent=1))
