Skip to content

lunartrace.display_sun

Repository display geometry from pinned NAIF DE421 kernels, not observation science.

Generates the display-only Sun direction and site elevation/azimuth carried by lunartrace.projection.DisplaySunProjection. The geometry is computed with SPICE (spiceypy) from the byte-pinned kernels listed in contracts/spice-kernels.manifest.json.

Frame and aberration MOON_ME_DE421 matches the Site01 source raster’s mean-Earth frame (MOON_PA would rotate the mapped coordinates). The aberration correction is NONE, meaning simultaneous geometric Sun/Moon positions, not apparent or photometric illumination.

Limits No terrain occlusion is computed. The result is a display parameter and never changes the standing of an observation.

Concurrency SPICE owns process-global state: use an otherwise empty kernel pool, and do not call other SPICE code concurrently with this generator. Calls to compute_display_sun within one process are serialised by an internal lock.

function

def load_kernel_manifest() -> list[DisplayKernel]

Read the committed SPICE kernel manifest and return its kernels in load order.

Reads spice-kernels.manifest.json from the package’s _contracts copy of contracts/. The manifest is validated for schema and frame; the kernel bytes themselves are not read here. Callers must pass each kernel through verify_kernel before use, so that cached files are never admitted on name alone.

  • list of DisplayKernel — Kernels in the order the manifest lists them, which is the load order.
  • ValueError — If the manifest schema is not lunartrace.spice_kernels/v0, its frame is not MOON_ME_DE421, or the kernel entries fail validation.

function

def verify_kernel(path: Path, kernel: DisplayKernel) -> None

Check that a kernel file matches its pinned size and SHA-256 digest.

Missing files and integrity mismatches are distinct, actionable failures.

NameTypeDescription
pathPathLocal path of the kernel file.
kernelDisplayKernelPinned name, size in bytes and SHA-256 digest to check against.
  • FileNotFoundError — If path does not exist.
  • ValueError — If the file size or SHA-256 digest does not match kernel.

function

def site01_centre() -> DisplaySite

Return the display location at the grid extent midpoint of the Site01 projection.

This is the midpoint of the grid extent, not the ROI centroid. The midpoint is transform(cols / 2, rows / 2) in rasterio affine order, at pixel corners. The projected midpoint is then inverted with a spherical south-polar stereographic projection, using the radius and lon_0 stated in the fixture CRS.

  • DisplaySite — Named Site01 grid extent centre, with latitude and longitude in degrees (east-positive).
  • ValueError — If the fixture’s crs_proj4 is not the documented spherical polar CRS +proj=stere +lat_0=-90 +lat_ts=-90 +lon_0=0 +x_0=0 +y_0=0 +R=1737400 +units=m.
  • FileNotFoundError — If the packaged copy of the Site01 fixture is absent (a broken installation).

The fixture is contracts/fixtures/pgda78-site01.slope-quality.projection.json, read from its packaged copy. The CRS radius is 1737400 m, which matches MOON_RADIUS_KM (1737.4 km). The inverse uses latitude = 2 atan(rho / (2 R)) - 90 degrees and longitude = atan2(x, y), where rho = hypot(x, y) and x and y are in metres.

function

def compute_display_sun(
epoch_utc: str,
kernel_dir: Path = DEFAULT_KERNEL_DIR,
*,
site: DisplaySite | None = None,
) -> DisplaySunProjection

Generate the display Sun direction and site elevation/azimuth for a UTC epoch.

NameTypeDescription
epoch_utcstrExplicit ISO-8601 UTC instant ending in Z, for example 2026-10-10T00:00:00Z. Local times without the Z suffix are rejected.
kernel_dirPathDirectory holding the pinned kernel files, named as in the manifest. Defaults to build/spice under the repository root. Kernels are not shipped in the wheel: an installed user must run tools/fetch_spice.py from a checkout, then pass the directory here. Default DEFAULT_KERNEL_DIR.
siteDisplaySiteDisplay location. When None, site01_centre is used. Default None.
  • DisplaySunProjection — Display-only result in frame MOON_ME_DE421 with aberration correction NONE.
  • ValueError — If epoch_utc does not end in Z or is not a valid ISO-8601 instant, or if a kernel fails the size or SHA-256 check in verify_kernel.
  • FileNotFoundError — If a kernel file is absent from kernel_dir. The message names tools/fetch_spice.py and the kernel_dir parameter.
  • RuntimeError — If the SPICE kernel pool is not empty on entry.

The direction is the Sun position relative to the Moon centre, in km, normalised to a unit vector. The site vector up is the unit normal of a sphere of radius MOON_RADIUS_KM. The site-to-Sun vector is local = S - R * up, where S is the Moon-to-Sun position. Elevation is asin(local . up / |local|) in degrees, and azimuth is atan2(east, north) modulo 360 degrees, measured clockwise from north.

The result is a display parameter, never tied to an observation or used to change its standing. Calls are serialised by an internal lock, and the kernel pool is cleared in a finally block even when a kernel fails to load.