Conversation
sun_moon_cut called get_body four times per evaluation (sun and moon for the altitude cuts, then both again inside moon_phase_angle) and built three identical AltAz frames. Fetch each body once, share one frame, and compute the phase angle from the coordinates already in hand. Output is bit-identical (A/B on 1k/10k/40k random observation times); the cut stage runs 1.67x faster, ~12% off ToO-mode wall time at 1M thrown. get_sun/get_moon/moon_phase_angle(time) keep their signatures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Target mode asked astropy for the exact source AltAz at every thrown time and exact sun/moon ephemerides at every valid time. Those are smooth functions over the observation window, so evaluate them exactly on a grid (simulation.target.ephemeris_step, default 60 s; 0 = exact) and cubic-interpolate to the requested times. The source is interpolated as a unit vector so azimuth wrap is harmless; sun/moon altitude and phase angle are interpolated directly. Scalar or few-point queries (fewer than the grid) still evaluate exactly. A/B vs exact at 200k thrown (24 h window): source position error 2e-8 rad, sun/moon altitude 2e-10 rad, phase 3e-11 rad; horizon, volume and sun/moon masks identical for steps up to 900 s. End-to-end compute at 1M thrown: identical row count and passing events, OMCINT relative difference 2.6e-11, wall 25.1 s -> 1.7 s. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The dask LocalCluster costs ~0.7 s to spawn and ~0.25 s to close, which was half the wall time of a 1M-throw Target run once the ToO geometry was fixed. CphotAng.__call__ and EAS.__call__ gain serial=True, which runs the same packed chunk kernel on the whole batch in this process. compute() now decides after geometry, when the valid count is known: below simulation.eas_parallel_threshold (default 150_000; 0 = always cluster) it runs serially and never starts a cluster; at or above it, the background cluster starts there and overlaps the spectra/tau/decay stages as before. A/B, seed-matched, every column and MC meta bit-identical both ways: Diffuse 99k valid: cluster 1.88 s, serial 1.10 s Diffuse 992k valid: cluster 3.99 s, serial 11.36 s Diffuse 3.97M valid: cluster 10.9 s, serial 45.5 s Target 39k valid: cluster 2.27 s, serial 0.74 s Target 194k valid: cluster 2.88 s, serial 3.07 s Fit: ~11 us/shower serial vs ~1.3 s + ~2.7 us/shower on the cluster, break-even ~150k valid showers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Target (ToO) mode was dominated by astropy coordinate work, not shower physics: at 1M thrown, 97% of a 28.9 s run was
get_body/AltAzevaluated independently at every thrown time. Three commits, each A/B'd against the previous state:sun_moon_cutfetches each ephemeris once (dd39545). It calledget_bodyfour times per evaluation (twice again insidemoon_phase_angle) and built three identicalAltAzframes. Bit-identical output; cut stage 1.67x faster.1055862). Newsimulation.target.ephemeris_step(default 60 s;0= exact per-time evaluation, the old behaviour). Source AltAz is interpolated as a unit vector (azimuth wrap-safe); sun/moon altitude and phase angle directly. Scalar/few-point queries still evaluate exactly. At 200k thrown: source error 2e-8 rad (astropy's own noise floor — 300 s gives the same), sun/moon 2e-10 rad, zero mask flips for steps up to 900 s. End-to-end 1M thrown: same rows and passing events,OMCINTrel. diff 2.6e-11, 25.1 s → 1.7 s.dc591c2). The dask cluster's ~1 s spawn/teardown was half the remaining wall time.CphotAng.__call__/EAS.__call__gainserial=True(same packed chunk kernel, whole batch, this process);compute()decides after geometry using newsimulation.eas_parallel_threshold(default 150 000;0= always cluster). Bit-identical both ways in Diffuse and Target at all sizes tested; break-even measured at ~150k valid (≈11 µs/shower serial vs ≈1.3 s + 2.7 µs/shower cluster).Net: 1M-throw Target run 28.9 s → 0.74 s; large Diffuse runs unchanged (still use the cluster).
A/B evidence
Serial vs cluster, seed-matched, every column + MC meta
array_equal:Also prototyped (not adopted) a closed-form ICRS→CIRS-once + Earth-rotation-angle transform for the source: 2.5e-6 rad error (polar motion + diurnal aberration missing), and with ERFA
apio13/atioq9e-7 rad and slower than the spline. The grid already exploits the same slow/fast structure and reaches astropy's noise floor.Reviewer notes
ephemeris_step = 0,eas_parallel_threshold = 0).test_configserialization expectations updated accordingly.get_sun,get_moon,moon_phase_angle(time)are unchanged; newsun_moon_state(time)andphase_angle_from_bodies(sun, moon)helpers.test_ephemeris_grid_matches_exactpins interpolated vs exact positions (<1e-6 rad) and identical cut masks on 5000 random times.refractive_indeximport incphotang.py; left alone as unrelated.Test plan
pytest test/core test/simulation/geometry test/simulation/eas_optical— 162 passed🤖 Generated with Claude Code