"""Chamfer (to the clean mesh) against the energy not yet decoded, per object, from ../report/knee.csv; knees starred.
-> ../report/img/knee_energy_chamfer.png"""
from pathlib import Path
import numpy as np, pandas as pd
import matplotlib; matplotlib.use("Agg"); import matplotlib.pyplot as plt
REP = Path(__file__).parent.parent / "report"
K = pd.read_csv(REP / "knee.csv")
STY = {"mesh": ("mesh route (clean)", "k", "-"), "pn0p6_10000": ("0.6 %, σ given", "tab:blue", "-"),
       "pn0p6_10000_s0": ("0.6 %, σ = 0", "tab:blue", "--"), "pn1p2_10000": ("1.2 %, σ given", "tab:red", "-"),
       "pn1p2_10000_s0": ("1.2 %, σ = 0", "tab:red", "--")}
objs = list(dict.fromkeys(K.object))
fig, axs = plt.subplots(2, 5, figsize=(22, 8.5), sharex=True)
for ax, o in zip(axs.ravel(), objs):
    for c, (lab, col, ls) in STY.items():
        g = K[(K.object == o) & (K.cloud == c)].sort_values("atoms")
        if not len(g):
            continue
        rem = np.maximum(1 - g.energy.values, 1e-7)  # energy not yet decoded; the full descriptor at 1e-7
        ax.semilogx(rem, g["mean"], ls, color=col, marker="o", ms=3, label=lab)
        k = g[g.is_knee == 1]
        ax.semilogx(np.maximum(1 - k.energy.values, 1e-7), k["mean"], "*", color=col, ms=14, mec="k")
    ax.invert_xaxis()
    ax.set_title(o); ax.grid(True, which="both", alpha=0.3); ax.set_ylim(0, None)
    ax.set_xlabel("energy not yet decoded (fraction; the full descriptor at 1e-7)"); ax.set_ylabel("Chamfer ×1e-3 (clean mesh)")
axs[0, 0].legend(fontsize=8)
fig.suptitle("Chamfer to the clean mesh as the atoms are decoded (6144 atoms, gwn + closing); ★ = the knee (Kneedle)", fontsize=12)
fig.tight_layout(); fig.savefig(REP / "img" / "knee_energy_chamfer.png", dpi=90)
print("saved")
