Source code for planetary_coverage.spice.limb

"""SPICE limb computation."""

import numpy as np

import spiceypy as sp

from ..math.vectors import vector_rejection


[docs]def limb_ip_pt(et_obs, observer_id, target_id, obs_frame, obs_ray, target_frame, abcorr='NONE'): r"""Limb impact parameter point on a target from a ray at the observer position. Impact parameter vector based on the ray emerging form the observer. No check is performed to know it the surface of the target is intersected. .. code-block:: text · target | ∖ | · | ∖ <- Target -> Impact parameter vector | · Impact parameter point ( ip vector ⟂ ray) | ⋰ | · | / <- Observer emerging Ray · Observer Parameters ---------- time: float Observer Ephemeris Time. observer_id: int Observer id code. target_id: int Target body id code. obs_frame: str Observer reference frame relative to which the ray's direction vector is expressed. obs_ray: tuple or list of tuple Ray direction vector emanating from the observer. target_frame: str Target reference frame relative to impact parameter vector is expressed (from the target center). abcorr: str, optional Aberration correction (default: 'None'). See ``Danger`` section below. Returns ------- (float, float, float) or np.ndarray Limb impact parameter XYZ coordinates in the target body fixed frame (expressed in km). If a list of time were provided, the results will be stored in a (3, N) array. Raises ------ NotImplementedError If a light time correction is required. Danger ------ No implementation of the limb impact parameter is directly available in the NAIF SPICE routines. In this function we tried to implement our own but support for light aberration correction is not implemented yet. Use it at your own risks. See Also -------- spiceypy.spiceypy.spkezp """ if abcorr.upper() != 'NONE': raise NotImplementedError('Light time correction are not implemented yet') # No light time correction s = 0 # Get the observer -> target vector target_j2000, lt = sp.spkezp(target_id, et_obs, 'J2000', abcorr, observer_id) # Invert the vector and compute the time obs_j2000 = np.negative(target_j2000) # Target -> Observer et_target = et_obs - s * lt # Target time # Inverted ray in J2000 frame when the observe received it cmat = sp.pxform(obs_frame, 'J2000', et_obs) ray_j2000 = sp.mxv(cmat, np.negative(obs_ray)) # Check that the ray is pointing to the target direction if np.dot(obs_j2000, ray_j2000) <= 0: return np.array([np.nan, np.nan, np.nan]) # Compute the impact parameter in J2000 frame ip_j2000 = vector_rejection(obs_j2000, ray_j2000) # Convert the impact parameter from J2000 to target fixed frame tmat = sp.pxform('J2000', target_frame, et_target) ip_target = sp.mxv(tmat, ip_j2000) return ip_target