#!/usr/bin/env python3 """Stream the DESI EDR epoviz rows into a row-level eigenmass receipt. This is a literal-data stress pass over the 669k-row DESI epoviz CSV. It avoids holding every row in memory by accumulating feature means and covariance with a streaming Welford update, then computes a small symmetric eigendecomposition. Boundary: this is an SMN/evidence-load mass direction over DESI epoviz rows. It is not physical mass, not dark-energy inference, and not a gas-density map. """ from __future__ import annotations import csv import gzip import hashlib import json import math from collections import Counter from datetime import datetime, timezone from pathlib import Path from typing import Any ROOT = Path(__file__).resolve().parents[2] DESI_GZ = ROOT / "shared-data/artifacts/stellar_gas_observation/desi_epoviz/EDR-Viz-Outreach-VAC.csv.gz" OUT_DIR = ROOT / "shared-data/data/stellar_gas_observation" DOCS_DIR = ROOT / "6-Documentation/docs" TIDDLER_DIR = ROOT / "6-Documentation/tiddlywiki-local/wiki/tiddlers" OUT_JSON = OUT_DIR / "desi_epoviz_row_eigenmass_probe.json" RECEIPT_JSON = OUT_DIR / "desi_epoviz_row_eigenmass_probe_receipt.json" DOC_MD = DOCS_DIR / "desi_epoviz_row_eigenmass_probe_2026-05-09.md" TIDDLER = TIDDLER_DIR / "DESI Epoviz Row Eigenmass Probe.tid" FEATURES = [ "x_glyr", "y_glyr", "z_glyr", "redshift", "rosette_sin", "rosette_cos", "tracer_QSO", "tracer_ELG", "tracer_LRG", "tracer_BGS", ] TRACERS = { "0": "QSO", "1": "ELG", "2": "LRG", "3": "BGS", } def sha256_file(path: Path) -> str: h = hashlib.sha256() with path.open("rb") as f: for chunk in iter(lambda: f.read(1024 * 1024), b""): h.update(chunk) return h.hexdigest() def dot(a: list[float], b: list[float]) -> float: return sum(x * y for x, y in zip(a, b)) def mat_vec(m: list[list[float]], v: list[float]) -> list[float]: return [dot(row, v) for row in m] def norm(v: list[float]) -> float: return math.sqrt(dot(v, v)) def normalize(v: list[float]) -> list[float]: n = norm(v) if n == 0: return [0.0 for _ in v] return [x / n for x in v] def jacobi_eigen_symmetric(matrix: list[list[float]], max_iter: int = 300, eps: float = 1e-12) -> tuple[list[float], list[list[float]], dict[str, Any]]: n = len(matrix) a = [row[:] for row in matrix] v = [[1.0 if i == j else 0.0 for j in range(n)] for i in range(n)] iterations = 0 final_max_offdiag = 0.0 converged = False for iteration in range(1, max_iter + 1): p, q = 0, 1 max_off = 0.0 for i in range(n): for j in range(i + 1, n): val = abs(a[i][j]) if val > max_off: max_off = val p, q = i, j iterations = iteration final_max_offdiag = max_off if max_off < eps: converged = True break if abs(a[p][p] - a[q][q]) < eps: angle = math.pi / 4.0 else: angle = 0.5 * math.atan2(2.0 * a[p][q], a[q][q] - a[p][p]) c = math.cos(angle) s = math.sin(angle) app = c * c * a[p][p] - 2.0 * s * c * a[p][q] + s * s * a[q][q] aqq = s * s * a[p][p] + 2.0 * s * c * a[p][q] + c * c * a[q][q] a[p][p] = app a[q][q] = aqq a[p][q] = 0.0 a[q][p] = 0.0 for k in range(n): if k == p or k == q: continue akp = c * a[k][p] - s * a[k][q] akq = s * a[k][p] + c * a[k][q] a[k][p] = akp a[p][k] = akp a[k][q] = akq a[q][k] = akq for k in range(n): vkp = c * v[k][p] - s * v[k][q] vkq = s * v[k][p] + c * v[k][q] v[k][p] = vkp v[k][q] = vkq return [a[i][i] for i in range(n)], v, { "method": "jacobi_symmetric", "max_iter": max_iter, "eps": eps, "iterations": iterations, "converged": converged, "final_max_offdiag": final_max_offdiag, } def eigen_residual(matrix: list[list[float]], eigenvalue: float, eigenvector: list[float]) -> float: av = mat_vec(matrix, eigenvector) residual = [av_i - eigenvalue * v_i for av_i, v_i in zip(av, eigenvector)] return norm(residual) def feature_row(row: dict[str, str]) -> list[float]: rosette = int(row["ROSETTE"]) angle = 2.0 * math.pi * (rosette % 20) / 20.0 tracer = TRACERS.get(row["TRACER"], "UNKNOWN") return [ float(row["X"]), float(row["Y"]), float(row["Z"]), float(row["REDSHIFT"]), math.sin(angle), math.cos(angle), 1.0 if tracer == "QSO" else 0.0, 1.0 if tracer == "ELG" else 0.0, 1.0 if tracer == "LRG" else 0.0, 1.0 if tracer == "BGS" else 0.0, ] def z_bin_cosmic(z: float) -> str: if z < 0.1: return "z_0_0p1" if z < 0.5: return "z_0p1_0p5" if z < 1.0: return "z_0p5_1" if z < 2.0: return "z_1_2" return "z_2_plus" def round_float(x: float) -> float: return round(x, 9) def build() -> tuple[dict[str, Any], dict[str, Any]]: if not DESI_GZ.exists(): raise FileNotFoundError(DESI_GZ) n = 0 d = len(FEATURES) means = [0.0] * d m2 = [[0.0] * d for _ in range(d)] tracer_counts: Counter[str] = Counter() z_counts: Counter[str] = Counter() rosette_counts: Counter[str] = Counter() redshift_min = math.inf redshift_max = -math.inf with gzip.open(DESI_GZ, "rt", newline="") as f: reader = csv.DictReader(f) required = {"TARGETID", "REDSHIFT", "ROSETTE", "TRACER", "X", "Y", "Z"} missing = required - set(reader.fieldnames or []) if missing: raise ValueError(f"missing columns: {sorted(missing)}") for row in reader: x = feature_row(row) n += 1 delta = [x[i] - means[i] for i in range(d)] for i in range(d): means[i] += delta[i] / n delta2 = [x[i] - means[i] for i in range(d)] for i in range(d): for j in range(i, d): m2[i][j] += delta[i] * delta2[j] tracer = TRACERS.get(row["TRACER"], f"UNKNOWN_{row['TRACER']}") z = float(row["REDSHIFT"]) tracer_counts[tracer] += 1 z_counts[z_bin_cosmic(z)] += 1 rosette_counts[row["ROSETTE"]] += 1 redshift_min = min(redshift_min, z) redshift_max = max(redshift_max, z) cov = [[0.0] * d for _ in range(d)] for i in range(d): for j in range(i, d): val = m2[i][j] / (n - 1) cov[i][j] = val cov[j][i] = val stds = [math.sqrt(max(cov[i][i], 0.0)) or 1.0 for i in range(d)] corr = [[cov[i][j] / (stds[i] * stds[j]) for j in range(d)] for i in range(d)] values, vectors_as_columns, solver = jacobi_eigen_symmetric(corr) order = sorted(range(d), key=lambda i: values[i], reverse=True) eigenvalues = [values[i] for i in order] dominant = normalize([vectors_as_columns[row][order[0]] for row in range(d)]) # Keep the direction readable: positive redshift and ELG/LRG direction. sign_anchor = dominant[FEATURES.index("redshift")] + dominant[FEATURES.index("tracer_ELG")] + dominant[FEATURES.index("tracer_LRG")] if sign_anchor < 0: dominant = [-x for x in dominant] residual = eigen_residual(corr, eigenvalues[0], dominant) total_positive = sum(x for x in eigenvalues if x > 0) explained = [x / total_positive if total_positive > 0 else 0.0 for x in eigenvalues] created = datetime.now(timezone.utc).isoformat(timespec="seconds") source_hash = sha256_file(DESI_GZ) result = { "schema": "desi_epoviz_row_eigenmass_probe_v0", "created": created, "decision": "ADMIT_DESI_ROW_EIGENMASS_HOLD_PHYSICAL_MASS", "claim_boundary": ( "Row eigenmass is an SMN/evidence-load direction over DESI EDR " "epoviz rows. It is not physical mass, not stellar mass, not a " "gas-density map, and not a cosmology fit." ), "source": { "csv_gz": str(DESI_GZ.relative_to(ROOT)), "sha256": source_hash, "doc": "https://data.desi.lbl.gov/doc/releases/edr/vac/epoviz/", }, "row_count": n, "feature_basis": FEATURES, "feature_means": {name: round_float(means[i]) for i, name in enumerate(FEATURES)}, "feature_stds": {name: round_float(stds[i]) for i, name in enumerate(FEATURES)}, "dominant_eigenvalue": round_float(eigenvalues[0]), "dominant_explained_mass_share": round_float(explained[0]), "eigensolver_diagnostics": { **solver, "dominant_residual_l2": round(residual, 12), "orthogonality_note": "Jacobi rotations return an orthonormal basis up to numeric roundoff; this receipt reports the dominant residual only.", }, "dominant_eigenvector": {name: round_float(dominant[i]) for i, name in enumerate(FEATURES)}, "eigenvalues": [round_float(x) for x in eigenvalues], "explained_mass_share": [round_float(x) for x in explained], "population_counts": { "tracers": {k: tracer_counts[k] for k in sorted(tracer_counts)}, "cosmic_redshift_bins": {k: z_counts[k] for k in sorted(z_counts)}, "rosettes": {k: rosette_counts[k] for k in sorted(rosette_counts, key=lambda x: int(x))}, "redshift_min": round_float(redshift_min), "redshift_max": round_float(redshift_max), }, "holds": [ "HOLD_PHYSICAL_MASS_INTERPRETATION", "HOLD_DIRECT_STELLAR_GAS_INFERENCE", "HOLD_OBJECT_LEVEL_MANGA_CROSSMATCH", "HOLD_SELECTION_FUNCTION_FIT", "HOLD_COSMOLOGY_FIT", ], } receipt = { "receipt_type": "desi_epoviz_row_eigenmass_probe_receipt", "created": created, "source_sha256": source_hash, "row_count": n, "dominant_eigenvalue": result["dominant_eigenvalue"], "dominant_explained_mass_share": result["dominant_explained_mass_share"], "eigensolver_diagnostics": result["eigensolver_diagnostics"], "decision": result["decision"], "validated_outputs": [ str(OUT_JSON.relative_to(ROOT)), str(DOC_MD.relative_to(ROOT)), str(TIDDLER.relative_to(ROOT)), ], } return result, receipt def write_docs(result: dict[str, Any]) -> None: vector_lines = "\n".join( f"- `{name}`: {value}" for name, value in result["dominant_eigenvector"].items() ) tracer_lines = "\n".join( f"- `{name}`: {value}" for name, value in result["population_counts"]["tracers"].items() ) z_lines = "\n".join( f"- `{name}`: {value}" for name, value in result["population_counts"]["cosmic_redshift_bins"].items() ) holds = "\n".join(f"- `{hold}`" for hold in result["holds"]) diag = result["eigensolver_diagnostics"] DOC_MD.write_text( f"""# DESI Epoviz Row Eigenmass Probe Status: `DESI_ROW_EIGENMASS` Decision: `{result['decision']}` This probe streams the DESI EDR epoviz CSV row-by-row and computes the dominant correlation eigenvector over geometry, redshift, rosette phase, and tracer identity. It is a literal-data stress pass over the DESI epoviz surface. Claim boundary: this is SMN/evidence-load mass, not physical mass, not stellar mass, not gas-density inference, and not a cosmology fit. ## Result Rows read: `{result['row_count']}` Dominant eigenvalue: ```text {result['dominant_eigenvalue']} ``` Dominant explained mass share: ```text {result['dominant_explained_mass_share']} ``` ## Dominant Eigenvector {vector_lines} ## Eigensolver Diagnostics ```text method: {diag['method']} converged: {diag['converged']} iterations: {diag['iterations']} final max off-diagonal: {diag['final_max_offdiag']} dominant residual L2: {diag['dominant_residual_l2']} ``` ## Population Counts Tracer counts: {tracer_lines} Cosmic redshift bins: {z_lines} ## Holds {holds} """, encoding="utf-8", ) TIDDLER.write_text( f"""title: DESI Epoviz Row Eigenmass Probe tags: StellarGasObservation DESI SemanticMassNumbers Eigenvector Receipts type: text/vnd.tiddlywiki Status: <> Decision: `{result['decision']}` This probe streams the DESI EDR epoviz rows directly and computes the dominant SMN/evidence-load eigenvector over geometry, redshift, rosette phase, and tracer identity. Rows read: `{result['row_count']}` Dominant eigenvalue: ``` {result['dominant_eigenvalue']} ``` Dominant explained mass share: ``` {result['dominant_explained_mass_share']} ``` Eigensolver: ``` converged={diag['converged']} iterations={diag['iterations']} residual_l2={diag['dominant_residual_l2']} ``` !! Dominant Eigenvector {vector_lines} !! Boundary This is not physical mass, not stellar mass, not direct gas-density inference, and not a cosmology fit. """, encoding="utf-8", ) def main() -> None: result, receipt = build() OUT_DIR.mkdir(parents=True, exist_ok=True) DOCS_DIR.mkdir(parents=True, exist_ok=True) TIDDLER_DIR.mkdir(parents=True, exist_ok=True) OUT_JSON.write_text(json.dumps(result, indent=2, sort_keys=True) + "\n", encoding="utf-8") RECEIPT_JSON.write_text(json.dumps(receipt, indent=2, sort_keys=True) + "\n", encoding="utf-8") write_docs(result) print(json.dumps(receipt, indent=2, sort_keys=True)) if __name__ == "__main__": main()