#!/usr/bin/env python3 """test_moon_composite.py — render a phase composite using real NASA data. Simulates what moon_phase_monthly.py does on the night of a full moon: 1. Fetch the NASA SVS Dial-a-Moon render for 2026-04-29T22:00Z. 2. Load the east camera frame (21-07-00.jpg) and check for a clear moon. 3. If clear: render — NASA moon with parallactic angle rotation → test_composite_out.jpg. 4. If not clear: exit with a message (no fallback image). Run from the sky-cam directory: python3 test_moon_composite.py Requires internet access to reach svs.gsfc.nasa.gov. """ import pathlib import sys from datetime import datetime, timezone HERE = pathlib.Path(__file__).resolve().parent sys.path.insert(0, str(HERE)) EAST_FRAME = HERE / '21-07-00.jpg' OUT_PATH = HERE / 'test_composite_out.jpg' # Obs time: 22:00 UTC on 2026-04-29 — aligns directly with NASA hourly renders. NASA_FETCH_UTC = datetime(2026, 4, 29, 22, 0, tzinfo=timezone.utc) MIN_QUALITY = 0.55 def main(): if not EAST_FRAME.exists(): print(f'ERROR: missing {EAST_FRAME}', file=sys.stderr) sys.exit(1) print('=== moon composite test ===') print(f'east frame : {EAST_FRAME.name} (2026-04-29 21:07 UTC)') print(f'NASA time : {NASA_FETCH_UTC.strftime("%Y-%m-%dT%H:00Z")}') print() # 1. Check east frame for clear moon detection print(f'checking moon in {EAST_FRAME.name} ...') try: from moon_detect import detect_moon det = detect_moon(str(EAST_FRAME)) quality = det.quality if det is not None else None except Exception as e: print(f' detection failed: {e}', file=sys.stderr) sys.exit(2) if quality is None or quality < MIN_QUALITY: print(f' quality={quality} — no clear moon detection — skipping (no fallback)') sys.exit(0) print(f' quality={quality:.3f} — clear shot confirmed') print() # 2. Fetch NASA Dial-a-Moon print(f'fetching NASA Dial-a-Moon for {NASA_FETCH_UTC.strftime("%Y-%m-%dT%H:00Z")} ...') try: import moon_dialamoon nasa_path = moon_dialamoon.fetch_for_time(NASA_FETCH_UTC) print(f' cached at {nasa_path}') except Exception as e: print(f' NASA fetch failed: {e}', file=sys.stderr) sys.exit(3) print() # 3. Render with parallactic angle rotation from moon_composite import render_phase_closeup caption = ( f'Full Moon — April 2026 — ' f'sky-cam east 2026-04-29 22:00 UTC — ' f'NASA SVS Dial-a-Moon' ) print(f'rendering {OUT_PATH.name} ...') render_phase_closeup( nasa_render_path=str(nasa_path), out_path=str(OUT_PATH), output_size=(1920, 1080), moon_height_pct=0.88, caption=caption, when_utc=NASA_FETCH_UTC, ) print(f'done -> {OUT_PATH}') if __name__ == '__main__': main()