| |
| |
|
|
| import csv |
| import math |
| from collections import defaultdict |
| from pathlib import Path |
|
|
| IN = Path("outputs/phase5a/task_vapre_splatatlas_repro.csv") |
| OUT = Path("outputs/phase1/per_cell_metrics_long.csv") |
| OUT.parent.mkdir(parents=True, exist_ok=True) |
|
|
| METHOD_COL = "method" |
| SCENE_COL = "scene" |
|
|
| METRICS = { |
| "psnr_splat": "psnr", |
| "ssim_splat": "ssim", |
| "lpips_splat": "lpips", |
| } |
|
|
| EXPECTED_METHODS = [ |
| "3dgsmcmc", "absgs", "atomgs", "conegs", "ges", "ghap", "gslpm", |
| "lapisgs", "reactgs", "vanilla_3dgs", |
| "2dgs", "gaussian_surfel", "gof", "pgsr", "scaffoldgs", |
| "coadaptgs", "erankgs", "gaussianpro", "minisplatting", |
| "opti3dgs", "steepgs", |
| "3dgs_dr", "analyticsplatting", "lod_gs", "mipsplatting", |
| "pixelgs", |
| "cdcgs", "hogs", "lightgaussian", "octree_gs", "trimgs", |
| ] |
|
|
| EXPECTED_SCENES = [ |
| "auditorium", "ballroom", "barn", "caterpillar", "courtroom", |
| "lighthouse", "museum", "palace", "playground", "temple", "train", "truck", |
| "bicycle", "bonsai", "counter", "flowers", "garden", "kitchen", "room", |
| "stump", "treehill", |
| "chair", "drums", "ficus", "hotdog", "lego", "materials", "mic", "ship", |
| "drjohnson", "playroom", |
| ] |
|
|
| def parse_float(x): |
| x = str(x).strip() |
| if x == "" or x.lower() in {"nan", "none", "null", "na", "n/a", "---"}: |
| return None |
| try: |
| v = float(x) |
| except ValueError: |
| return None |
| if math.isnan(v) or math.isinf(v): |
| return None |
| return v |
|
|
| buckets = defaultdict(list) |
|
|
| with open(IN, "r", newline="", encoding="utf-8") as f: |
| reader = csv.DictReader(f) |
| fields = set(reader.fieldnames or []) |
|
|
| required = {METHOD_COL, SCENE_COL, *METRICS.keys()} |
| missing = required - fields |
| if missing: |
| raise ValueError(f"Missing columns in {IN}: {missing}. Actual columns={reader.fieldnames}") |
|
|
| for row in reader: |
| method = row[METHOD_COL].strip() |
| scene = row[SCENE_COL].strip() |
|
|
| for src_col, metric in METRICS.items(): |
| value = parse_float(row[src_col]) |
| if value is None: |
| continue |
| buckets[(method, scene, metric)].append(value) |
|
|
| rows = [] |
| for (method, scene, metric), vals in sorted(buckets.items()): |
| |
| value = sum(vals) / len(vals) |
| rows.append({ |
| "method_key": method, |
| "scene": scene, |
| "metric": metric, |
| "value": f"{value:.10g}", |
| }) |
|
|
| with open(OUT, "w", newline="", encoding="utf-8") as f: |
| writer = csv.DictWriter(f, fieldnames=["method_key", "scene", "metric", "value"]) |
| writer.writeheader() |
| writer.writerows(rows) |
|
|
| methods = sorted({r["method_key"] for r in rows}) |
| scenes = sorted({r["scene"] for r in rows}) |
|
|
| print("Wrote:", OUT) |
| print("rows:", len(rows)) |
| print("methods:", len(methods), methods) |
| print("scenes:", len(scenes), scenes) |
|
|
| for metric in ["psnr", "ssim", "lpips"]: |
| cells = {(r["method_key"], r["scene"]) for r in rows if r["metric"] == metric} |
| print(metric, "cells:", len(cells)) |
|
|
| missing_methods = sorted(set(EXPECTED_METHODS) - set(methods)) |
| extra_methods = sorted(set(methods) - set(EXPECTED_METHODS)) |
| missing_scenes = sorted(set(EXPECTED_SCENES) - set(scenes)) |
| extra_scenes = sorted(set(scenes) - set(EXPECTED_SCENES)) |
|
|
| print("missing_methods:", missing_methods) |
| print("extra_methods:", extra_methods) |
| print("missing_scenes:", missing_scenes) |
| print("extra_scenes:", extra_scenes) |
|
|
| print("erankgs × lego:") |
| for r in rows: |
| if r["method_key"] == "erankgs" and r["scene"].lower() == "lego": |
| print(r) |
|
|
| if len(methods) != 31: |
| raise AssertionError(f"Expected 31 methods, got {len(methods)}") |
| if len(scenes) != 31: |
| raise AssertionError(f"Expected 31 scenes, got {len(scenes)}") |
| if missing_methods or extra_methods: |
| raise AssertionError(f"Method mismatch: missing={missing_methods}, extra={extra_methods}") |
| if missing_scenes or extra_scenes: |
| raise AssertionError(f"Scene mismatch: missing={missing_scenes}, extra={extra_scenes}") |
|
|
| expected_rows = 31 * 31 * 3 |
| if len(rows) != expected_rows: |
| print(f"[WARN] Expected {expected_rows} metric rows, got {len(rows)}.") |
| print("[WARN] Missing metric values will be skipped in dataset means.") |
| print("[WARN] If an entire method-dataset block is missing, it will appear as --- in Appendix E.") |
|
|