Source code for m4opt.constraints._earth_limb
from typing import override
import numpy as np
from astropy import units as u
from astropy.constants import R_earth
from astropy.coordinates import AltAz, EarthLocation, SkyCoord
from astropy.time import Time
from ._core import Constraint
def _get_angle_from_earth_limb(
observer_location: EarthLocation, target_coord: SkyCoord, obstime: Time
) -> u.Quantity[u.physical.angle]:
alt = target_coord.transform_to(
AltAz(location=observer_location, obstime=obstime)
).alt
x, y, z = observer_location.geocentric
z = np.sqrt(np.square(x) + np.square(y) + np.square(z))
with np.errstate(invalid="ignore"):
limb_alt = np.arccos(R_earth / z)
return alt + limb_alt
[docs]
class EarthLimbConstraint(Constraint):
"""
Constrain the angle from the Earth limb.
Parameters
----------
min
Minimum angular separation from the Earth's limb.
Notes
-----
This constraint assumes a spherical Earth, so it is only accurate to about
a degree for observers in very low Earth orbit (height of 100 km).
Examples
--------
>>> from astropy.constants import R_earth
>>> from astropy.coordinates import EarthLocation, SkyCoord
>>> from astropy.time import Time
>>> from astropy import units as u
>>> from m4opt.constraints import EarthLimbConstraint
>>> observer_location = EarthLocation.from_geocentric(0 * u.m, 0 * u.m, 2 * R_earth)
>>> target_coord = SkyCoord(300 * u.deg, -30 * u.deg)
>>> obstime = Time.now()
>>> constraint = EarthLimbConstraint(10 * u.deg)
>>> constraint(observer_location, target_coord, obstime)
np.True_
"""
def __init__(self, min: u.Quantity[u.physical.angle]):
self.min = min
[docs]
@override
def __call__(self, *args):
return _get_angle_from_earth_limb(*args) >= self.min