Skip to content

DERIVED_POINTS

TheDaniel166 edited this page Oct 26, 2026 · 1 revision

Named derived points

The additional source-qualified hypothetical constructions cover Arta, anchored Selena, Abramov Proserpina, prescribed Waldemath/Vulcan orbits and historical prediction realizations under a separate discovery API.

moira.derived_points admits four explicit models in three families:

Model ID Meaning Dated calculation needs a kernel?
baker_vulcan Baker's symbolic Sun/Mercury longitude rule Yes
mean_priapus Mean lunar perigee, opposite the selected mean apogee No
osculating_priapus Osculating lunar perigee, opposite the existing true apogee Yes
orbital_second_focus Geometric second focus of a bound osculating ellipse Yes

Discover them with derived_point_catalog() or GET /v1/derived-points/catalog. These are separate model identities, with no physical NAIF IDs of their own. They are opt-in calculations and are not added to the default planetary chart or Hamburg Uranian body catalog. Bare Vulcan, Priapus, Selena, Arta, and Proserpina are not implicit selectors here.

Baker Vulcan

Solar Fire's official Vulcan calculation documentation describes Baker's rule: move Mercury three degrees toward Sun, stopping at Sun when Mercury is within three degrees. There is no generally accepted physical Vulcan ephemeris. This implementation admits the named rule, not the asserted existence of a planet, Weston's orbital model, or Hamburg Vulkanus.

For the signed shortest separation d = Mercury - Sun, in (-180, 180):

longitude = (Sun + sign(d) * max(abs(d) - 3, 0)) mod 360

baker_vulcan_from_longitudes(sun_longitude, mercury_longitude) is kernel-free. Its inputs must share a longitude frame; its receipt says the frame is supplied by the caller. Inputs are normalized separately. Exactly antipodal inputs fail because the direction toward Sun is ambiguous. Both the clamp and zodiac wraparound are explicit. No latitude, distance, motion, retrograde flag, or physical state is fabricated.

baker_vulcan_at(jd_ut, reader=...) uses the existing apparent geocentric Sun and Mercury reductions in the true ecliptic/equinox of date. Its result retains those input longitudes, UT1/TT/TDB epochs, kernel identity and source convention. The result is a symbolic longitude derived from those positions.

Mean and osculating Priapus

mean_priapus(jd_ut, nutation=True) is the exact antipode of moira.nodes.mean_lilith() in the same selected frame. The default frame is true ecliptic/equinox of date; nutation=False selects mean ecliptic/equinox of date. The inherited IERS polynomial speed excludes the nutation derivative even in the true frame. The result makes that limitation explicit.

osculating_priapus(jd_ut, reader=...) is the exact antipode of moira.nodes.true_lilith_with_truth(). It retains the signed speed and the complete parent apogee receipt, including clock, Earth-Moon gravitational parameter, frame, kernel identity and finite-difference rate policy. A constant 180-degree translation preserves the signed rate. This API does not introduce a new lunar dynamical model.

These names do not denote the seven-year White Moon Selena, Avestan Priap, Arta, or the independently defined interpolated/natural perigee convention.

Orbital second focus

For an ellipse with semimajor axis a and eccentricity vector e_vector, the center lies at -a * e_vector relative to its first focus. Reflecting the first focus through that center gives:

second_focus_vector = -2 * a * e_vector
focal_distance = 2 * a * eccentricity

This is different from apocenter, whose distance is a * (1 + eccentricity). For any point on the ellipse, the distances to its two foci sum to 2a.

orbital_second_focus(body, jd_ut, center=..., frame=..., reader=...) delegates body admission, time binding, state extraction, gravity and singularity policy to moira.orbits.osculating_elements(). Both center and frame are required:

  • Centers: OrbitalCenter.SUN or OrbitalCenter.EARTH, subject to strict core body/center admission.
  • Frames: J2000_ECLIPTIC, MEAN_ECLIPTIC_OF_DATE, or TRUE_ECLIPTIC_OF_DATE, subject to the existing frame validity intervals.

Coordinates are relative to the selected central focus, in AU. This is instantaneous geometric conic geometry, without apparent-place corrections, light time, or an Earth-observer translation of a Sun-relative result. The source body retains its real identity; the focal point does not inherit its NAIF ID as a new body. The full typed source elements and provenance survive Python and REST transport. second_focus_from_elements(elements) also accepts an existing OsculatingElements result without another kernel evaluation.

Status Vector and distance Angular result
DEFINED Finite elliptic second-focus vector and distance Longitude/latitude; longitude is null at an exact ecliptic pole
COINCIDENT_FOCI Exactly circular: zero vector and distance Both null
CIRCULAR_DIRECTION_UNDEFINED Nonzero eccentricity below the source circular threshold: vector null, distance retained Both null
NON_ELLIPTIC Parabolic/hyperbolic: vector and distance null Both null

The last status means this elliptic product is not evaluable; it makes no claim that hyperbolas lack a second geometric focus. Strict orbital input, resource, coverage, center and frame errors propagate unchanged.

Python and facade usage

All listed functions and result vessels are exported by moira and moira.facade, as well as their owning module.

from datetime import datetime, timezone
from moira import Moira, OrbitalCenter, OrbitalFrame, mean_priapus

mean = mean_priapus(2451545.0, nutation=False)  # UT1; kernel-free

engine = Moira(kernel_path="/path/to/de441.bsp")
dt = datetime(2026, 10, 26, tzinfo=timezone.utc)
vulcan = engine.baker_vulcan(dt)
perigee = engine.osculating_priapus(dt)
mean = engine.mean_priapus(dt, nutation=False)
focus = engine.orbital_second_focus(
    "Moon", dt, center=OrbitalCenter.EARTH,
    frame=OrbitalFrame.TRUE_ECLIPTIC_OF_DATE,
)

Datetime facade methods convert UTC to UT1 and use the instance-owned reader for kernel-bound computations. Numerical function epochs and REST jd_ut are UT1, not UTC, TT or TDB.

REST endpoints

Method Path Request
GET /v1/derived-points/catalog None; kernel-free
POST /v1/derived-points/baker-vulcan/from-longitudes sun_longitude, mercury_longitude; kernel-free
POST /v1/derived-points/baker-vulcan jd_ut
POST /v1/derived-points/priapus/mean jd_ut, optional Boolean nutation (default true); kernel-free
POST /v1/derived-points/priapus/osculating jd_ut
POST /v1/derived-points/second-focus body (name or integer ID), jd_ut, center, frame

Requests forbid extra fields, Boolean numeric inputs, nonfinite numbers and implicit numeric-string coercion. Responses use named typed schemas in OpenAPI, under the Derived Points catalog family. There is no generic unqualified hypothetical-body dispatcher.

Validation covers documented Baker examples and boundaries, covariance under zodiac rotation, independently constructed rotated ellipses and the focal distance-sum invariant, circular/polar/non-elliptic outcomes, existing frozen Horizons holdouts at identical TDB epochs, lunar rate/truth retention, facade clock/reader binding, and REST schema/receipt behavior. No scientific fixture or existing acceptance threshold is changed.

Clone this wiki locally