Source code for across.tools.visibility.constraints.pointing

from typing import Literal

import numpy as np
import numpy.typing as npt
from astropy.coordinates import SkyCoord  # type: ignore[import-untyped]
from astropy.time import Time  # type: ignore[import-untyped]

from ...core.enums.constraint_type import ConstraintType
from ...core.schemas import Coordinate
from ...ephemeris import Ephemeris
from ...footprint import Pointing
from .base import ConstraintABC, get_slice


[docs] class PointingConstraint(ConstraintABC): """ Footprint based pointing constraint. A Pointing is defined as a Footprint with a start and end time. This constraint will calculate whether a target was within any set of pointings. Attributes ---------- pointings List of Pointing objects. start_time AstropyDateTime defining the start of the pointing end_time AstropyDateTime defining the end of the pointing """
[docs] pointings: list[Pointing]
[docs] name: Literal[ConstraintType.POINTING] = ConstraintType.POINTING
[docs] short_name: Literal["Pointing"] = "Pointing"
[docs] def __call__( self, time: Time, ephemeris: Ephemeris, coordinate: SkyCoord, ) -> npt.NDArray[np.bool_]: """ Evaluate the constraint at the given time(s) and coordinate. Parameters ---------- time : Time The time(s) at which to evaluate the constraint. coordinate : SkyCoord The sky coordinates to check against the constraint. ephemeris : Ephemeris The ephemeris position(s) at which to evaluate the constraint. This parameter is not used in this specific constraint but is included for compatibility with the base class. Returns ------- ndarray A boolean array indicating whether the constraint is satisfied at the given time(s) and position(s). If time is scalar, returns a single boolean value. The constraint is satisfied if the coordinate is outside the footprint, OR if the time is outside the start and end time. """ # For each pointing, is the coordinate within the footprint # and time range? # Find a slice for the part of the ephemeris that we're using. i = get_slice(time, ephemeris) # Build a time window for the selected ephemeris interval. time_window = ephemeris.timestamp[i] in_constraint = np.ones(len(time_window), dtype=np.bool_) for pointing in self.pointings: # Is the target inside the footprint of the pointing? in_footprint = np.asarray( [ pointing.footprint.contains(Coordinate(ra=coordinate.ra.deg, dec=coordinate.dec.deg)) * len(time_window) ], dtype=np.bool_, ) # Are the times inside the start and end time of the pointing? in_pointing_time = np.array( [t >= pointing.start_time and t < pointing.end_time for t in time_window] ) # Return the result as True or False, or an array of True/False # "True" means the target is constrained, because it is either outside the # footprint or outside the pointing time range. in_constraint &= ~(in_footprint & in_pointing_time) return in_constraint