"""volume_atoms / volume_atoms_fast against volume.py (layer-centre ring sum) and the mesh volume; out/volume_atoms.csv."""
import sys
import timeit
sys.argv = [sys.argv[0], "x"]
from hull import OBJECTS, OUT  # noqa: E402
from volume import volume  # noqa: E402
from volume_atoms import volume_atoms, volume_atoms_fast  # noqa: E402
import numpy as np, pandas as pd, trimesh, fcp  # noqa: E402
rows = []
for name, p in OBJECTS.items():
    m = trimesh.load(p, force="mesh")
    for layers, atoms in ((128, 1024), (128, 6144), (256, 6144)):
        d = fcp.encode(m, atoms=atoms, layers=layers, device="cpu")
        r, a, b = volume(d), volume_atoms(d), volume_atoms_fast(d)
        n = 20000
        rows.append(dict(obj=name, layers=layers, atoms_req=atoms, atoms=d.n_atoms, parts=len(d.parts),
                         diff_ring=abs(b - r) / abs(r), diff_np=abs(b - a) / abs(a), err_pct=100 * (b / m.volume - 1),
                         us_fast=timeit.timeit(lambda: volume_atoms_fast(d), number=n) / n * 1e6,
                         us_numpy=timeit.timeit(lambda: volume_atoms(d), number=2000) / 2000 * 1e6))
d = pd.DataFrame(rows)
d.to_csv(OUT / "volume_atoms.csv", index=False)
print(d.round(6).to_string())
print(d.groupby(["layers", "atoms_req"]).agg(err_med=("err_pct", lambda x: x.abs().median()), err_max=("err_pct", lambda x: x.abs().max()),
      us_med=("us_fast", "median"), us_max=("us_fast", "max"), np_us_med=("us_numpy", "median"), diff_max=("diff_ring", "max")).round(4))
