| import os, json, numpy as np |
|
|
| OUTPUT_ROOT = "/root/autodl-tmp/SplatAtlas/outputs/error_responsibility" |
| PROF_DIR = os.path.join(OUTPUT_ROOT, "_profiles") |
|
|
| METHODS = ['vanilla_3dgs', 'analyticsplatting', 'erankgs', 'ges', 'lightgaussian', 'minisplatting', 'opti3dgs', 'pgsr', 'steepgs'] |
| SCENES = ['bicycle','bonsai','counter','flowers','garden','kitchen','room','stump','treehill', |
| 'auditorium','ballroom','barn','caterpillar','courtroom','lighthouse','museum','palace','playground','temple','train','truck', |
| 'DrJohnson','Playroom', |
| 'Chair','Drums','Ficus','Hotdog','Lego','Materials','Mic','Ship'] |
| METRICS = ["psnr_full", "sh_net_effect", "sh_corruption_rate", "opacity_net_effect", "coverage", "coverage_error_fraction", "residual_error"] |
|
|
| data = {m: {} for m in METHODS} |
| status_counts = {m: {"PASS": 0, "WARN": 0, "FAIL": 0} for m in METHODS} |
| failed_cells = [] |
|
|
| |
| for m in METHODS: |
| for s in SCENES: |
| p = os.path.join(OUTPUT_ROOT, f"{m}_{s}", "counterfactual_summary.json") |
| if os.path.exists(p): |
| with open(p) as f: |
| d = json.load(f) |
| data[m][s] = d |
| st = d.get("sanity_status", "FAIL") |
| status_counts[m][st] = status_counts[m].get(st, 0) + 1 |
| if st == "FAIL": |
| failed_cells.append(f"{m}_{s}: {d.get('sanity_failures', [])}") |
|
|
| medians = {m: {} for m in METHODS} |
| for m in METHODS: |
| for k in METRICS: |
| vals = [data[m][s][k] for s in SCENES if s in data[m] and data[m][s].get(k) is not None] |
| medians[m][k] = float(np.median(vals)) if vals else 0.0 |
|
|
| |
| |
| sorted_by_psnr = sorted(METHODS, key=lambda x: medians[x]["psnr_full"]) |
| best_window = [] |
| min_psnr_range = 9999 |
|
|
| for i in range(len(sorted_by_psnr) - 3): |
| window = sorted_by_psnr[i:i+4] |
| rng = medians[window[-1]]["psnr_full"] - medians[window[0]]["psnr_full"] |
| if rng < min_psnr_range: |
| min_psnr_range = rng |
| best_window = window |
|
|
| def calc_iqr_stats(vals_list): |
| if not vals_list: return None, None, None |
| med = float(np.median(vals_list)) |
| abs_iqr = float(np.percentile(vals_list, 75) - np.percentile(vals_list, 25)) |
| rel_iqr = (abs_iqr / abs(med) * 100) if med != 0 else None |
| return med, abs_iqr, rel_iqr |
|
|
| sat_psnr_vals = [medians[m]["psnr_full"] for m in best_window] |
| _, _, sat_psnr_rel_iqr = calc_iqr_stats(sat_psnr_vals) |
|
|
| sat_results = {"subset_methods": best_window, "psnr_range_db": min_psnr_range, "psnr_rel_iqr": sat_psnr_rel_iqr, "metrics": {}} |
| for k in METRICS: |
| if k == "psnr_full": continue |
| vals = [medians[m][k] for m in best_window] |
| _, _, rel_iqr = calc_iqr_stats(vals) |
| sat_results["metrics"][k] = { |
| "rel_iqr": rel_iqr, |
| "ratio_vs_psnr": (rel_iqr / sat_psnr_rel_iqr) if (rel_iqr is not None and sat_psnr_rel_iqr) else None |
| } |
|
|
| with open(os.path.join(PROF_DIR, "psnr_saturated_subset_analysis.json"), "w") as f: |
| json.dump(sat_results, f, indent=4) |
|
|
| |
| strat_results = {} |
| for m in METHODS: |
| if m == "vanilla_3dgs": continue |
| strat_results[m] = {} |
| for k in METRICS: |
| if k == "psnr_full": continue |
| delta = medians[m][k] - medians["vanilla_3dgs"][k] |
| strat_results[m][k] = {"delta": delta, "sign": "+" if delta > 0 else ("-" if delta < 0 else "0")} |
|
|
| with open(os.path.join(PROF_DIR, "method_family_stratified.json"), "w") as f: |
| json.dump(strat_results, f, indent=4) |
|
|
| |
| print("=== 1. Execution Sanity Status ===") |
| print(f"{'Method':<20} | {'PASS':<6} | {'WARN':<6} | {'FAIL':<6}") |
| print("-" * 45) |
| for m in METHODS: |
| print(f"{m:<20} | {status_counts[m]['PASS']:<6} | {status_counts[m]['WARN']:<6} | {status_counts[m]['FAIL']:<6}") |
| print(f"\nTotal FAILS across all {len(METHODS)*len(SCENES)} cells: {len(failed_cells)}") |
|
|
| print(f"\n=== 2. PSNR Saturated Subset Analysis ===") |
| print(f"Subset identified: {best_window}") |
| print(f"PSNR Relative IQR of this subset: {sat_psnr_rel_iqr:.2f}% (Range: {min_psnr_range:.2f} dB)") |
| print(f"\n{'Metric':<25} | {'Rel IQR (%)':<15} | {'Ratio vs PSNR':<15}") |
| print("-" * 60) |
| for k in METRICS: |
| if k == "psnr_full": continue |
| d = sat_results["metrics"][k] |
| rel = f"{d['rel_iqr']:.2f}%" if d['rel_iqr'] else "N/A" |
| rat = f"{d['ratio_vs_psnr']:.1f}x" if d['ratio_vs_psnr'] else "N/A" |
| print(f"{k:<25} | {rel:<15} | {rat:<15}") |
|
|
| print(f"\n=== 3. Family Stratification (Sign vs Vanilla) ===") |
| print(f"{'Method':<20} | {'sh_net':<8} | {'sh_corr':<8} | {'opa_net':<8} | {'cov_err':<8} | {'resid':<8}") |
| print("-" * 70) |
| for m in METHODS: |
| if m == "vanilla_3dgs": continue |
| d = strat_results[m] |
| print(f"{m:<20} | {d['sh_net_effect']['sign']:<8} | {d['sh_corruption_rate']['sign']:<8} | {d['opacity_net_effect']['sign']:<8} | {d['coverage_error_fraction']['sign']:<8} | {d['residual_error']['sign']:<8}") |
|
|
|
|