Download tools/generate_appendix_rows.py from KCBtheone/SplatAtlas: direct link, hf CLI and curl.
- Browser
- Download file 8.7 kB
-
https://huggingface.co/KCBtheone/SplatAtlas/resolve/main/tools/generate_appendix_rows.py
- Command line
-
hf download hf://KCBtheone/SplatAtlas/tools/generate_appendix_rows.py
-
curl -L -o generate_appendix_rows.py https://huggingface.co/KCBtheone/SplatAtlas/resolve/main/tools/generate_appendix_rows.py
8.7 kB
| from __future__ import annotations | |
| import sys | |
| import os | |
| from pathlib import Path | |
| import pandas as pd | |
| # ----------------------------------------------------------------------------- | |
| # 稳健路径配置 | |
| # ----------------------------------------------------------------------------- | |
| PROJECT_ROOT = Path("/root/autodl-tmp/SplatAtlas") | |
| # App C 候选输入 | |
| APP_C_SRC_FULL = PROJECT_ROOT / "outputs" / "phase2" / "task_2_3_appE_full.csv" | |
| APP_C_SRC_FILT = PROJECT_ROOT / "outputs" / "phase2" / "task_2_3_appE_filtered_P01_P04.csv" | |
| # App D 输入 | |
| APP_D_SRC = PROJECT_ROOT / "outputs" / "phase4" / "task_4_1_seed_variance_summary_reconstructed.csv" | |
| OUT_DIR = PROJECT_ROOT / "tex" | |
| OUT_DIR.mkdir(parents=True, exist_ok=True) | |
| APP_C_OUT = OUT_DIR / "appC_paired_rows.tex" | |
| APP_D_OUT = OUT_DIR / "appD_seed_summary_rows.tex" | |
| SEED_P95 = 0.384 | |
| # ----------------------------------------------------------------------------- | |
| # 映射字典 | |
| # ----------------------------------------------------------------------------- | |
| VARIANT_DISPLAY = { | |
| "pgsr": "PGSR", | |
| "erankgs": "eRankGS", | |
| "lightgaussian": "LightGaussian", | |
| "steepgs": "SteepGS", | |
| } | |
| METHOD_DISPLAY = { | |
| "vanilla_3dgs": r"\texttt{vanilla\_3dgs}", | |
| "analyticsplatting": r"\texttt{analyticsplatting}", | |
| "erankgs": r"\texttt{erankgs}", | |
| "ges": r"\texttt{ges}", | |
| "lightgaussian": r"\texttt{lightgaussian}", | |
| "minisplatting": r"\texttt{minisplatting}", | |
| "opti3dgs": r"\texttt{opti3dgs}", | |
| "pgsr": r"\texttt{pgsr}", | |
| "steepgs": r"\texttt{steepgs}", | |
| "3dgsmcmc": r"\texttt{3dgsmcmc}", | |
| } | |
| SCENE_DISPLAY = { | |
| "bicycle": "Bicycle", "bonsai": "Bonsai", "counter": "Counter", | |
| "flowers": "Flowers", "garden": "Garden", "kitchen": "Kitchen", | |
| "room": "Room", "stump": "Stump", "treehill": "Treehill", | |
| "auditorium": "Auditorium", "ballroom": "Ballroom", "barn": "Barn", | |
| "caterpillar": "Caterpillar", "courtroom": "Courtroom", "lighthouse": "Lighthouse", | |
| "museum": "Museum", "palace": "Palace", "playground": "Playground", | |
| "temple": "Temple", "train": "Train", "truck": "Truck", | |
| "drjohnson": "DrJohnson", "playroom": "Playroom", | |
| "chair": "Chair", "drums": "Drums", "ficus": "Ficus", "hotdog": "Hotdog", | |
| "lego": "Lego", "materials": "Materials", "mic": "Mic", "ship": "Ship", | |
| } | |
| def fmt_scene(key) -> str: | |
| k = str(key).strip().lower() | |
| name = SCENE_DISPLAY.get(k, str(key)) | |
| return rf"\textsc{{{name}}}" | |
| def fmt_signed(x, prec: int = 3) -> str: | |
| if pd.isna(x): return "---" | |
| return f"{x:+.{prec}f}" | |
| def fmt_unsigned(x, prec: int = 3) -> str: | |
| if pd.isna(x): return "---" | |
| return f"{x:.{prec}f}" | |
| # ----------------------------------------------------------------------------- | |
| # 生成逻辑 | |
| # ----------------------------------------------------------------------------- | |
| def generate_app_c() -> int: | |
| if APP_C_SRC_FULL.exists(): | |
| print(f"[App C] reading {APP_C_SRC_FULL}") | |
| df = pd.read_csv(APP_C_SRC_FULL) | |
| print(f"[App C] loaded {len(df)} rows total from FULL CSV") | |
| df = df[df["pair_id"].isin(["P01", "P02", "P03", "P04"])].copy() | |
| print(f"[App C] after P01-P04 filter: {len(df)} rows (expect 124)") | |
| elif APP_C_SRC_FILT.exists(): | |
| print(f"[App C] reading {APP_C_SRC_FILT}") | |
| df = pd.read_csv(APP_C_SRC_FILT) | |
| print(f"[App C] loaded {len(df)} rows total from FILTERED CSV (expect 124)") | |
| else: | |
| print("ERROR: missing App C source files. Searching for candidates:") | |
| os.system('find /root/autodl-tmp/SplatAtlas/outputs -name "task_2_3_appE*.csv"') | |
| sys.exit(1) | |
| df["_scene_disp"] = df["scene"].astype(str).str.lower().map(SCENE_DISPLAY).fillna(df["scene"]) | |
| df = df.sort_values(["pair_id", "_scene_disp"]).reset_index(drop=True) | |
| lines: list[str] = [] | |
| lines.append("% AUTOGENERATED by tools/generate_appendix_rows.py - DO NOT EDIT BY HAND.\n") | |
| last_pair = None | |
| n_data_rows = 0 | |
| for _, row in df.iterrows(): | |
| if last_pair is not None and row["pair_id"] != last_pair: | |
| lines.append(r"\midrule" + "\n") | |
| last_pair = row["pair_id"] | |
| variant_disp = VARIANT_DISPLAY.get(row["variant"], row["variant"]) | |
| scene_disp = fmt_scene(row["scene"]) | |
| cells = [ | |
| row["pair_id"], | |
| variant_disp, | |
| scene_disp, | |
| fmt_signed(row["delta_psnr_full"]), | |
| fmt_signed(row["delta_sh_net_effect"]), | |
| fmt_signed(row["delta_sh_corruption_rate"]), | |
| fmt_signed(row["delta_opacity_net_effect"]), | |
| fmt_signed(row["delta_opacity_pathology_rate"]), | |
| fmt_signed(row["delta_coverage_error_fraction"]), | |
| fmt_signed(row["delta_residual_error"]), | |
| ] | |
| lines.append(" & ".join(cells) + r" \\" + "\n") | |
| n_data_rows += 1 | |
| APP_C_OUT.write_text("".join(lines)) | |
| print(f"[App C] wrote {APP_C_OUT} ({n_data_rows} data rows)") | |
| return n_data_rows | |
| def generate_app_d() -> int: | |
| if not APP_D_SRC.exists(): | |
| print("ERROR: missing App D source files. Searching for candidates:") | |
| os.system('find /root/autodl-tmp/SplatAtlas/outputs -name "*seed_variance*summary*.csv"') | |
| sys.exit(1) | |
| print(f"[App D] reading {APP_D_SRC}") | |
| df = pd.read_csv(APP_D_SRC) | |
| print(f"[App D] loaded {len(df)} rows total") | |
| scene_col = "SceneNormalized" if "SceneNormalized" in df.columns else "Scene" | |
| method_col = "Method" | |
| out_lines: list[str] = [] | |
| out_lines.append("% AUTOGENERATED by tools/generate_appendix_rows.py - DO NOT EDIT BY HAND.\n") | |
| n_data_rows = 0 | |
| for scene_idx, scene in enumerate(["bonsai", "lego"]): | |
| if scene_idx > 0: | |
| out_lines.append(r"\midrule" + "\n") | |
| df_scene = df[df[scene_col].astype(str).str.lower() == scene].copy() | |
| df_scene = df_scene.sort_values(method_col) | |
| scene_disp = fmt_scene(scene) | |
| for _, row in df_scene.iterrows(): | |
| method_key = row[method_col] | |
| escaped_key = str(method_key).replace("_", r"\_") | |
| method_disp = METHOD_DISPLAY.get(method_key, rf"\texttt{{{escaped_key}}}") | |
| psnr_mean = row["PSNR_mean"] | |
| psnr_std = row["PSNR_std"] | |
| psnr_min = row["PSNR_min"] | |
| psnr_max = row["PSNR_max"] | |
| status = str(row.get("Status", "OK")).strip().upper() | |
| if status == "METHOD_FAILURE": | |
| flag = r"\textsc{Failure}" | |
| elif status == "OUTLIER" or (not pd.isna(psnr_std) and psnr_std > SEED_P95): | |
| flag = r"\textsc{Outlier}" | |
| else: | |
| flag = "---" | |
| cells = [ | |
| method_disp, scene_disp, | |
| fmt_unsigned(psnr_mean), fmt_unsigned(psnr_std), | |
| fmt_unsigned(psnr_min), fmt_unsigned(psnr_max), | |
| flag, | |
| ] | |
| out_lines.append(" & ".join(cells) + r" \\" + "\n") | |
| n_data_rows += 1 | |
| APP_D_OUT.write_text("".join(out_lines)) | |
| print(f"[App D] wrote {APP_D_OUT} ({n_data_rows} data rows)") | |
| return n_data_rows | |
| # ----------------------------------------------------------------------------- | |
| # Main & Sanity Checks | |
| # ----------------------------------------------------------------------------- | |
| if __name__ == "__main__": | |
| print("\n========================================================") | |
| print("1. Generating LaTeX row fragments") | |
| print("========================================================") | |
| c_rows = generate_app_c() | |
| d_rows = generate_app_d() | |
| print("\n========================================================") | |
| print("2. SANITY CHECKS") | |
| print("========================================================") | |
| print(f"[Check] App C output rows equals 124: {'PASS' if c_rows == 124 else 'FAIL'} ({c_rows})") | |
| print(f"[Check] App D output rows equals 20: {'PASS' if d_rows == 20 else 'FAIL'} ({d_rows})") | |
| # 验证 App D 中的特殊标记 | |
| with open(APP_D_OUT, "r") as f: | |
| d_content = f.read() | |
| ana_outlier = ("analyticsplatting" in d_content and "Outlier" in d_content) | |
| era_failure = ("erankgs" in d_content and "Failure" in d_content) | |
| print(f"[Check] analyticsplatting has \\textsc{{Outlier}}: {'PASS' if ana_outlier else 'FAIL'}") | |
| print(f"[Check] erankgs has \\textsc{{Failure}}: {'PASS' if era_failure else 'FAIL'}") | |
| print("\n========================================================") | |
| print("Generated:") | |
| print(f"- {APP_C_OUT}: {c_rows} rows") | |
| print(f"- {APP_D_OUT}: {d_rows} rows") | |
| print("========================================================") | |