-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathv69_tomographic_redshift_evolution.py
More file actions
160 lines (142 loc) · 7.29 KB
/
Copy pathv69_tomographic_redshift_evolution.py
File metadata and controls
160 lines (142 loc) · 7.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
"""V69 — Tomographic-bin redshift evolution of (Om, s8) direction.
X6 prereg locked at commit 026d1e9. Asks whether the (Omega_m,
sigma_8) banana orientation rotates with effective redshift across
tomographic bins WITHIN each shear survey.
Implementation note: per-tomographic-bin (Omega_m, sigma_8) chains
or marginalized posteriors are NOT a standard data product in the
KiDS-1000, DES Y3, or HSC Y3 public releases. The released chains
are joint-over-bins (or joint with statistic separation, e.g.
COSEBIs vs BP vs xi+/-, all joint over bins). Per-bin posteriors
would require re-running the likelihood code with bin masks applied,
which the X6 stop condition explicitly forbids ("Do not attempt to
extraction methods not in the original survey release. ...Do not
re-run likelihoods.").
This script performs the data-availability audit, documents the
inventory, and fires the locked outcome D (data unavailable).
"""
from __future__ import annotations
import json
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
DATA = ROOT / "data"
RESULTS = ROOT / "results"
def _audit_des_y3() -> dict:
info = {"survey": "DES Y3", "expected_n_bins": 4,
"expected_zeff": [0.34, 0.52, 0.74, 0.96]}
chain = DATA / "des_y3" / "chain_3x2pt_lcdm_SR_maglim.txt"
info["available_chain"] = str(chain.relative_to(ROOT)) if chain.exists() else None
info["chain_kind"] = ("joint 3x2pt (cosmic shear + GGL + galaxy clustering); "
"joint over all tomographic bins (per-bin chains NOT released)")
info["per_bin_chain_available"] = False
info["per_bin_summary_available"] = False
info["reason_unavailable"] = (
"DES Y3 cosmic-shear-only and 3x2pt chain releases provide joint "
"posteriors marginalized over all source tomographic bins; per-source-bin "
"(Omega_m, sigma_8) marginalized posteriors are not separately released "
"in machine-readable form. Reconstructing per-bin posteriors would "
"require re-running the DES Y3 likelihood with bin masks, which is "
"forbidden by X6 stop condition."
)
return info
def _audit_kids() -> dict:
info = {"survey": "KiDS-1000", "expected_n_bins": 5,
"expected_zeff": [0.26, 0.40, 0.56, 0.79, 0.98]}
chain_root = (DATA / "kids1000" / "KiDS1000_cosmis_shear_data_release"
/ "chains_and_config_files" / "main_chains_iterative_covariance")
if chain_root.exists():
statistics = sorted([p.name for p in chain_root.iterdir() if p.is_dir()])
else:
statistics = []
info["available_chain_statistics"] = statistics # cosebis, bp, xipm
info["chain_kind"] = ("per-statistic (COSEBIs, BP, xi+/-) chains, each "
"joint over the 5 tomographic bins; per-bin chains "
"NOT released")
info["per_bin_chain_available"] = False
info["per_bin_summary_available"] = False
info["reason_unavailable"] = (
"KiDS-1000 public release provides per-statistic chains "
"(COSEBIs, band powers, xi+/-) each marginalized over all 5 tomographic "
"bins. Per-bin (Omega_m, sigma_8) posteriors are not separately released. "
"Reconstructing them requires re-running CosmoSIS/MontePython likelihoods "
"with bin masks, forbidden by X6 stop condition."
)
return info
def _audit_hsc() -> dict:
info = {"survey": "HSC Y3", "expected_n_bins": 4,
"expected_zeff": [0.30, 0.61, 0.82, 1.18]}
chain_dir = DATA / "hsc_y3_chains"
if chain_dir.exists():
candidates = sorted([p.name for p in chain_dir.iterdir()])
else:
candidates = []
info["chain_dir_contents"] = candidates
info["available_chain"] = None # checked below
summary = DATA / "hsc_y3" / "summary_lcdm.json"
info["available_summary"] = str(summary.relative_to(ROOT)) if summary.exists() else None
info["chain_kind"] = ("Gaussian summary only (literature mean + sigma + correlation "
"from Li+23 / Dalal+23)")
info["per_bin_chain_available"] = False
info["per_bin_summary_available"] = False
info["reason_unavailable"] = (
"HSC Y3 chains are not on disk in this repository; the catalog entry "
"is a literature Gaussian summary from Li+23 / Dalal+23. Even if the "
"joint chain were available, per-bin posteriors are not in the public "
"release. Reconstructing requires re-running the HSC likelihood, "
"forbidden by X6 stop condition."
)
return info
def main() -> None:
print("V69: tomographic-bin redshift evolution audit (X6 prereg).")
print("Checking per-survey per-bin (Omega_m, sigma_8) posterior availability...")
surveys = [_audit_des_y3(), _audit_kids(), _audit_hsc()]
n_accessible = sum(1 for s in surveys
if s["per_bin_chain_available"] or s["per_bin_summary_available"])
for s in surveys:
print(f"\n {s['survey']}: expected {s['expected_n_bins']} bins at "
f"z_eff={s['expected_zeff']}")
print(f" chain kind: {s['chain_kind']}")
print(f" per-bin chain available: {s['per_bin_chain_available']}")
print(f" per-bin summary available: {s['per_bin_summary_available']}")
print(f" reason: {s['reason_unavailable']}")
print(f"\n surveys with per-bin posteriors: {n_accessible} / 3")
if n_accessible == 0:
outcome = "D-data_unavailable_per_stop_condition"
msg = ("Per-bin (Omega_m, sigma_8) posteriors are not in machine-"
"readable form in any of the three shear surveys' public "
"releases. X6 outcome D fires per the locked prereg's stop "
"condition. The within-shear question cannot be answered "
"with publicly-released data alone.")
else:
outcome = "X6-incomplete_partial_data"
msg = (f"Only {n_accessible}/3 surveys have per-bin posteriors; "
"X6 prereg requires N>=10 bins for outcome A, so partial "
"data does not suffice for the locked rule.")
print(f"\n=== OUTCOME: {outcome} ===")
print(msg)
out = {
"battery": "V69",
"prereg": "X6 (preregs/X6_v69_tomographic_redshift_evolution_prereg.md, locked at 026d1e9)",
"branch": "optimal_transport",
"description": (
"Tomographic-bin redshift evolution audit. Asks whether per-bin "
"(Omega_m, sigma_8) banana orientation rotates with z_eff_bin "
"within each shear survey."
),
"audit_per_survey": surveys,
"n_surveys_with_per_bin_data": n_accessible,
"outcome_category": outcome,
"interpretation": msg,
"remediation_required_for_outcome_ABC": (
"Re-run the per-survey likelihood codes (CosmoSIS for DES Y3/KiDS, "
"the HSC pipeline for HSC Y3) with bin masks applied to extract "
"per-bin (Omega_m, sigma_8) posteriors. This is outside the scope "
"of the V63-V72 paper program and the X6 stop condition forbids "
"it as part of V69."
),
}
RESULTS.mkdir(parents=True, exist_ok=True)
out_path = RESULTS / "v69_tomographic_redshift_evolution_results.json"
out_path.write_text(json.dumps(out, indent=2, default=float))
print(f"\nWrote {out_path.relative_to(ROOT)}")
if __name__ == "__main__":
main()