#!/usr/bin/env python3 """Postprocess existing 4K/limited maps only; never invokes a renderer. Usage: summarize_4k.py [OUT_DIR] OUT_DIR defaults to /local/adaptive_bounds_4k and must contain ``r100_4k_hmax2.grlens``, ``r100_4k_hmax8.grlens`` and ``attempts.json``. Writes summary.json in OUT_DIR. Cost scope note: accepted/rejected/RHS sums cover the final persistent map vertices only. Nonpersistent discarded refinement probes are not stored in the v3 map, so these sums are not full-render executed RHS totals. """ import json import re from pathlib import Path import sys from mesh_maps import load, compare ROOT = Path(__file__).resolve().parents[2] OUT = Path(sys.argv[1]).resolve() if len(sys.argv) > 1 else \ ROOT / 'local/adaptive_bounds_4k' def main(): summaries = {} meshes = {} for upper in (2, 8): name = f'r100_4k_hmax{upper}' summaries[name], meshes[upper] = load(OUT / (name + '.grlens')) text = (OUT / (name + '.log')).read_text() initial = int(re.search(r'tracing (\d+) initial rays', text).group(1)) generations = [int(n) for n in re.findall( r'refinement generation \d+ tracing (\d+) samples', text)] summaries[name]['requested_samples_including_nonpersistent_probes'] = \ initial + sum(generations) summaries[name]['initial_samples'] = initial summaries[name]['refinement_samples_per_generation'] = generations summaries[name]['trace_wall_seconds'] = sum( float(x) for x in re.findall( r'(?:initial ray trace|adaptive ray-trace refinement) ' r'finished in ([\d.]+) s', text)) ledger = OUT / 'attempts.json' if ledger.exists(): for entry in json.loads(ledger.read_text()): if entry.get('state') == 'completed': summaries[f'r100_4k_hmax{entry["upper"]}']['wall_seconds'] = \ entry['wall_seconds'] summaries['comparison'] = compare(meshes[2], meshes[8]) a, b = (summaries[f'r100_4k_hmax{upper}'] for upper in (2, 8)) summaries['relative_reduction'] = { key: 1 - b[key] / a[key] for key in ('accepted', 'rhs', 'wall_seconds', 'trace_wall_seconds')} summaries['comparison']['triangle_payload_identical'] = \ a['triangle_sha256'] == b['triangle_sha256'] summaries['cost_scope'] = ( 'accepted/rejected/RHS sums cover final persistent vertices only; ' 'nonpersistent discarded refinement probes are not in the v3 map. ' 'Do not interpret them as full-render executed RHS totals.') (OUT / 'summary.json').write_text(json.dumps(summaries, indent=2) + '\n') print(json.dumps(summaries, indent=2)) if __name__ == '__main__': main()