Geometer and SPICE engine#

class cassini_upyp.geometry.spice_engine.Geometer(target, observer, et, offset=array([0, 0, 0]))#

Bases: object

Low-level geometry engine for apparent target/line-of-sight computations.

Geometer wraps a set of SPICE and geometric routine calls to compute viewing geometry for a given target body as seen from a given observer at a specified ephemeris time. It provides vectors and helpers to compute the apparent limb (ellipse), the terminator, visible latitude/longitude grid lines, and line-of-sight (LOS) tangent/intersection quantities used by the higher-level cassini_upyp.geometry.geometry.Geometry container.

Parameters:
  • target (str) – SPICE name of the target body (e.g., "TITAN"). Case-insensitive.

  • observer (str) – SPICE name of the observer (e.g., "CASSINI"). Case-insensitive.

  • et (float) – Ephemeris time (seconds past J2000, TDB).

  • offset (array-like, optional) – Optional offset vector passed to the geometry engine to be applied on the main target body, for example to compensate some known bias. Default is (0, 0, 0) as it should remain unused.

Variables:
  • planet (str) – Uppercase target name.

  • observer (str) – Uppercase observer name.

  • et (float) – Ephemeris time (seconds past J2000, TDB).

  • radii (ndarray, shape (3,)) – Target tri-axial radii [km] as returned by SPICE BODVRD.

  • obs_from_planet_brf (ndarray, shape (3,)) – Observer position vector in the target body-fixed frame (IAU_<TARGET>), i.e. vector from target center to observer, with optional offset added.

  • planet_from_obs_j2k (ndarray, shape (3,)) – Target position vector in J2000 as seen from the observer (LT+S).

  • sun_from_obs_j2k (ndarray, shape (3,)) – Sun position vector in J2000 as seen from the observer (LT+S).

  • target_DEC (target_RA,) – Apparent target center coordinates (RA, Dec) in radians (J2000).

  • target_distance (float) – Apparent distance from observer to target center (same units as SPICE output).

  • rotation_J2K_IAU (rotation_IAU_J2K,) – Rotation matrices between the target body-fixed frame and J2000 at et.

  • planet_to_sun_brf (ndarray, shape (3,)) – Vector from target to Sun expressed in the target body-fixed frame.

Notes

All SPICE kernels required for the target/observer configuration must be loaded before instantiating this class.

See also

cassini_upyp.geometry.geometry.Geometry

High-level container building additional products (FOV, stars, plots).

get_ellipse(npoints=100, altitude=0, flag_dayside=True)#

Compute the apparent target limb as an ellipse and optionally flag day/night points.

The limb is computed in the target body-fixed frame using SPICE edlimb for a triaxial ellipsoid (with an optional altitude offset applied to the radii to compute iso-altitude ellipse). The resulting limb points are returned as direction vectors from the observer, expressed in the J2000 frame.

If flag_dayside is True, each limb point is classified as belonging to the illuminated hemisphere (day side) or not, based on the Sun direction in the target body-fixed frame. The returned arrays are reordered so that all day-side points are grouped together (then night-side points), following the ordering produced by cassini_upyp.geometry.computational.order_bool().

Parameters:
  • npoints (int, optional) – Number of points used to sample the limb ellipse. Default is 100.

  • altitude (float, optional) – Altitude added to each ellipsoid radius when computing the limb [km]. Default is 0.

  • flag_dayside (bool, optional) – If True, also return a boolean mask identifying points on the day side. Default is True.

Returns:

(limb_points, dayside) where:

  • limb_pointsnumpy.ndarray, shape (npoints, 3)

    Observer-to-limb direction vectors expressed in J2000.

  • daysidenumpy.ndarray of bool, shape (npoints,), or None

    Boolean mask indicating day-side limb points after reordering, or None if flag_dayside is False.

Return type:

tuple

Notes

  • The limb is computed for a triaxial ellipsoid using SPICE edlimb and

converted to center/axes form with el2cgv. - Day-side classification relies on a visibility test performed in the body-fixed frame (see cassini_upyp.geometry.computational.is_visible()).

is_visible(points, starmode=False, threshold=1e-06)#

Test whether points are visible from the observer above the target ellipsoid.

Calls cassini_upyp.geometry.computational.is_visible().

Parameters:
  • points (array-like) – Vectors (in the target body-fixed frame) from the target center to the points to be tested.

  • starmode (bool, optional) – Reserved for future use. Currently ignored. Default is False.

  • threshold (float, optional) – Visibility threshold passed to cassini_upyp.geometry.computational.is_visible(). Default is 1e-6.

Returns:

Boolean mask indicating which points are visible.

Return type:

numpy.ndarray of bool

get_terminator(npoints=100, full=False)#

Compute the apparent terminator curve (day/night boundary) as seen by the observer.

The terminator is computed by calling SPICE edlimb with the Sun direction vector expressed in the target body-fixed frame, producing the limb of the illumination ellipse. The resulting points are then expressed as direction vectors from the observer and rotated into the J2000 frame.

By default, only the portion of the terminator that is visible from the observer is returned. If full is True, visibility is not enforced and the full sampled curve is returned.

Parameters:
  • npoints (int, optional) – Number of points used to sample the terminator ellipse. Default is 100.

  • full (bool, optional) – If True, return the full sampled terminator without applying the visibility mask. Default is False.

Returns:

Array of shape (M, 3) containing observer-to-terminator direction vectors expressed in J2000, where M <= npoints when full is False.

Return type:

numpy.ndarray

get_lon_line(lon, latgrid=None)#

Compute the visible portion of a target longitude line.

The longitude line is generated on the target ellipsoid, transformed into observer-centered vectors in the target body-fixed frame, filtered for visibility from the observer, then rotated into the J2000 frame.

Parameters:
  • lon (float) – Longitude of the meridian to compute, in radians (body-fixed).

  • latgrid (array-like or None, optional) – Latitude sampling grid in radians. If None, uses 37 points uniformly spaced from -π/2 to π/2 with a step of 5°.

Returns:

Array of shape (M, 3) containing observer-to-surface direction vectors along the visible part of the meridian, expressed in J2000.

Return type:

numpy.ndarray

get_lat_line(lat, longrid=None)#

Compute the visible portion of a target latitude line.

The latitude line is generated on the target ellipsoid, transformed into observer-centered vectors in the target body-fixed frame, filtered for visibility from the observer, then rotated into the J2000 frame.

Parameters:
  • lat (float) – Latitude of the parallel to compute, in radians (body-fixed).

  • longrid (array-like or None, optional) – Longitude sampling grid in radians. If None, uses 37 points uniformly spaced from 0 to 2*π with a step of 10°.

Returns:

Array of shape (M, 3) containing observer-to-surface direction vectors along the visible part of the parallel, expressed in J2000.

Return type:

numpy.ndarray

LOS_tangent(LOS, J2000=True)#

Compute line-of-sight (LOS) tangent-point geometry on the target ellipsoid.

For each input LOS direction vector, this method computes the closest approach (tangent point) and/or the intersection point to the target triaxial ellipsoid as seen from the observer, then derives standard geometric quantities at that point (longitude, latitude, altitude, solar zenith angle, phase angle, emission angle, and local solar time).

By default, LOS vectors are assumed to be expressed in J2000 and are rotated into the target body-fixed frame (IAU_<TARGET>) before intersection/tangent computations.

Parameters:
  • LOS (array-like) – Array of LOS direction vectors. Expected shape is (N, 3).

  • J2000 (bool, optional) – If True (default), interpret LOS in J2000 and rotate it into the target body-fixed frame before computations. If False, LOS is assumed to already be expressed in the target body-fixed frame.

Returns:

Structured array of shape (N,) with fields:

  • lon : Intersection longitude [°].

  • lat : Intersection latitude [°].

  • alt : Tangent point altitude above the reference ellipsoid [km]. (Negative if LOS intersects the ellipsoid)

  • sza : Solar zenith angle [°] at the intersection point.

  • phase : Phase angle [°] at the intersection point.

  • ems : Emission angle [°] at the intersection point.

  • lt : Local solar time [hours] (0–24) at the intersection point.

  • t_lon : Longitude of the closest point to the ellipsoid center along the LOS (tangent point) [°].

  • t_lat : Latitude of the closest point to the ellipsoid center along the LOS (tangent point) [°].

  • t_sza : Solar zenith angle at the tangent point [°].

  • t_phase : Phase angle at the tangent point [°].

  • t_ems : Emission angle at the tangent point [°].

  • t_lt : Local solar time at the tangent point [hours] (0–24).

Return type:

numpy.ndarray

Notes

  • The tangent point is computed via cassini_upyp.geometry.computational.intersect() with closest_point=True. The intersection point (if it exists) is computed with closest_point=False.

  • Longitudes are flipped for Titan (lon = 360 - lon) to match the westward-positive convention.

  • Local solar time is computed from longitude relative to the sub-solar longitude and wrapped into [0, 24).

  • The intersection altitude is not given since it is a trivial 0.

See also

cassini_upyp.geometry.computational.intersect()

Compute LOS intersection / closest-approach with an ellipsoid.

cassini_upyp.geometry.computational.ellipsoid_xyz()

Convert Cartesian coordinates to (lon, lat, alt) on an ellipsoid.

cassini_upyp.geometry.computational.vec_angle()

Compute angles between vectors.