From 51f0acdf2e3ba33af6ed3dc6a9db23c1526d9aa1 Mon Sep 17 00:00:00 2001 From: Kasim Necdet Percinel Date: Wed, 2 Sep 2026 16:48:40 +0000 Subject: [PATCH 1/3] Resolve /position ambiguous body names to JPL Horizons IDs GET /position/ with a bare major-body name (earth, sun, ...) failed: JPL Horizons treats it as a wildcard (e.g. "earth" -> "EARTH*") and raises "Multiple major-bodies match string" instead of returning a position. Map the ambiguous names to their unambiguous Horizons body-center IDs (earth -> 399, etc.); spacecraft names (e.g. SDO) and unknown values pass through unchanged. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01YWMb14TXe3icvCsvwENZnd --- app/ephemeris.py | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/app/ephemeris.py b/app/ephemeris.py index bd0edce..9500d57 100644 --- a/app/ephemeris.py +++ b/app/ephemeris.py @@ -3,8 +3,39 @@ from sunpy.coordinates import get_horizons_coord +# JPL Horizons treats a bare major-body name as a wildcard, so "earth" becomes +# "EARTH*" and matches both the planet's body center and its planet-moon +# barycenter (e.g. "Earth" (399) and "Earth-Moon Barycenter" (3)). That +# ambiguity makes Horizons raise "Multiple major-bodies match string" instead +# of returning a position. Map the ambiguous names to their unambiguous +# Horizons body-center IDs so a request like /position/earth resolves to the +# geocenter (399). Spacecraft names (e.g. "SDO") are already unambiguous and +# pass through untouched. +_HORIZONS_BODY_IDS = { + "sun": 10, + "mercury": 199, + "venus": 299, + "earth": 399, + "moon": 301, + "mars": 499, + "jupiter": 599, + "saturn": 699, + "uranus": 799, + "neptune": 899, + "pluto": 999, +} + + +def _resolve_observatory(observatory_name: str): + """ + Translate an ambiguous major-body name (case-insensitive) into its JPL + Horizons body-center ID, leaving spacecraft and other names untouched. + """ + return _HORIZONS_BODY_IDS.get(observatory_name.strip().lower(), observatory_name) + + def get_position(observatory_name: str, start_time: Time, end_time: Time): time_range = end_time - start_time hours = int(time_range.to("hour").value) times = Time([start_time + i * 3600 * u.second for i in range(hours + 1)]) - return get_horizons_coord(observatory_name, times) + return get_horizons_coord(_resolve_observatory(observatory_name), times) From 8e2b38a12546047d0b0f4c9e7900c8f3c7a8e556 Mon Sep 17 00:00:00 2001 From: Kasim Necdet Percinel Date: Wed, 2 Sep 2026 16:59:18 +0000 Subject: [PATCH 2/3] fix string body names for positions of sunpy --- app/ephemeris.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/ephemeris.py b/app/ephemeris.py index 9500d57..182d827 100644 --- a/app/ephemeris.py +++ b/app/ephemeris.py @@ -2,7 +2,6 @@ from astropy.time import Time from sunpy.coordinates import get_horizons_coord - # JPL Horizons treats a bare major-body name as a wildcard, so "earth" becomes # "EARTH*" and matches both the planet's body center and its planet-moon # barycenter (e.g. "Earth" (399) and "Earth-Moon Barycenter" (3)). That From 073c704fcc1db1961fab5d470c2a68ff72a103b2 Mon Sep 17 00:00:00 2001 From: Kasim Necdet Percinel Date: Wed, 2 Sep 2026 20:42:26 +0000 Subject: [PATCH 3/3] Specify ambiguity values for horizon body ids, specify which value we select when selecting body in parameter, inside the comments --- app/ephemeris.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/ephemeris.py b/app/ephemeris.py index 182d827..2cb67f0 100644 --- a/app/ephemeris.py +++ b/app/ephemeris.py @@ -11,17 +11,17 @@ # geocenter (399). Spacecraft names (e.g. "SDO") are already unambiguous and # pass through untouched. _HORIZONS_BODY_IDS = { - "sun": 10, - "mercury": 199, - "venus": 299, - "earth": 399, - "moon": 301, - "mars": 499, - "jupiter": 599, - "saturn": 699, - "uranus": 799, - "neptune": 899, - "pluto": 999, + "sun": 10, # Sun (no barycenter ambiguity) + "mercury": 199, # Mercury body center, not Mercury Barycenter (1) + "venus": 299, # Venus body center, not Venus Barycenter (2) + "earth": 399, # Earth geocenter, not Earth-Moon Barycenter (3) + "moon": 301, # Moon (Earth's moon) body center + "mars": 499, # Mars body center, not Mars Barycenter (4) + "jupiter": 599, # Jupiter body center, not Jupiter Barycenter (5) + "saturn": 699, # Saturn body center, not Saturn Barycenter (6) + "uranus": 799, # Uranus body center, not Uranus Barycenter (7) + "neptune": 899, # Neptune body center, not Neptune Barycenter (8) + "pluto": 999, # Pluto body center, not Pluto Barycenter (9) }