Source code for giant.catalogs.meta_catalog

"""
This module defines the abstract base class (abc) for defining GIANT star catalogs that will work for Stellar OpNav
and camera calibration as well as the column definitions for the dataframe used to contain stars in GIANT.

The abc documents the required interface that must be implemented for each star catalog for it to be fully
functional in GIANT.  As such, when you define a new catalog in GIANT you should subclass this class and be sure to
implement all of its abstract methods. You should only worry about this abc when you are defining a new catalog.  If
you are using an existing catalog then you can ignore this documentation and read the documentation for the catalog
you are using for more specific details.

The column definitions are stored as 2 module attributes :attr:`GIANT_COLUMNS` and :attr:`GIANT_TYPES` which specify the
column names and the column types respectively of the dataframe used to store star records for use in GIANT.

Use
---

To implement a full function GIANT catalog, you must implement the following instance attribute

============================================= ==========================================================================
Instance Attribute                            Description
============================================= ==========================================================================
:attr:`~.Catalog.include_proper_motion`       boolean flag specifying whether to apply proper motion to the queried
                                              locations to translate them to the specified time before returning.
                                              Technically this isn't actually required, but it is strongly recommended.
============================================= ==========================================================================

In addition, you need to implement the following method

============================================= ==========================================================================
Method                                        Description
============================================= ==========================================================================
:attr:`~.Catalog.query_catalog`           A method which queries the catalog for requested Ra/Dec/Mag of stars
                                              and, if requested, applies proper motion to translate those stars to the
                                              requested time.
============================================= ==========================================================================

So long as your class implements these things it will be fully functional in GIANT and can be used for star
identification purposes.
"""

from abc import ABCMeta, abstractmethod

from datetime import datetime

from typing import Union, Optional, List, Type, Dict, Iterable, Sequence, Any

import numpy as np
import pandas as pd

from giant.utilities.spherical_coordinates import radec_to_unit, unit_to_radec
from giant.ray_tracer.utilities import correct_stellar_aberration
from giant.camera_models import CameraModel
from giant.image import OpNavImage

from giant._typing import DOUBLE_ARRAY


GIANT_COLUMNS: List[str] = ['ra', 'dec', 'distance', 'ra_proper_motion', 'dec_proper_motion', 'mag',
                            'ra_sigma', 'dec_sigma', 'distance_sigma', 'ra_pm_sigma', 'dec_pm_sigma', 'epoch']
"""
This specifies the name of the DataFrame columns used to store star observations in GIANT.

These columns represent the minimum set of data that GIANT needs to know about a star to use it for star identification.
A description of each column follows.

===================== ======== =================================================================================
column                units    description
===================== ======== =================================================================================
`'ra'`                deg      The right ascension of the star after correcting for proper motion
`'dec'`               deg      The declination of the star after correcting for proper motion
`'distance'`          km       The distance to the star from the Solar system barycenter (converted from
                               parallax). This column has a default value of 5.428047027e15 if no parallax
                               information is provided by the catalog.
`'ra_proper_motion'`  deg/year The proper motion for the right ascension
`'dec_proper_motion'` deg/year The proper motion for the declination
`'mag'`               N/A      The apparent magnitude of the star according to the star catalog
`'ra_sigma'`          deg      The formal uncertainty in the right ascension according to the catalog
`'dec_sigma'`         deg      The formal uncertainty in the declination according to the catalog
`'distance_sigma'`    km       The formal uncertainty in the distance according to the catalog 
                               (converted from parallax).  This has a default value of 
                               1.9949433041226756e+19 km for stars with no parallax information.
`'ra_pm_sigma'`       deg/year The formal uncertainty in the right ascension proper motion according to 
                               the catalog
`'dec_pm_sigma'`      deg/year The formal uncertainty in the declination proper motion according to the
                               catalog
`'epoch'`             MJD year The current epoch of the ra/dec/proper motion as a float
===================== ======== =================================================================================

"""


GIANT_TYPES: Dict[str, Type] = dict(zip(GIANT_COLUMNS, [np.float64] * len(GIANT_COLUMNS)))
"""
This specifies the data type for each column of the GIANT star dataframe.

This is generally all double precision float values, though that could change in a future release.
"""


[docs] class Catalog(metaclass=ABCMeta): """ This is the abstract base class for star catalogs that GIANT can use for star identification. This class defines the minimum required attributes and methods that GIANT expects when interfacing with a star catalog. It is also set up to implement duck typing, so if you don't want to you don't need to subclass this class directly when defining a new catalog, though it is still strongly encouraged. To define a new Catalog you pretty much only need to implement a :meth:`query_catalog` method with the call signature specified in the abstract method documentation. This is what GIANT will use when retrieving stars from the catalog. Beyond that, you should probably also implement and use an instance attribute :attr:`include_proper_motion` (although this is not required) as a flag that the user could use to turn proper motion applying on or off on a call to :meth:`query_catalog`. If you are just trying to use a GIANT catalog, you don't need to worry about this class, instead see one of the concrete implementations in :mod:`.ucac`, :mod:`.tycho`, or :mod:`.giant_catalog` .. note:: Because this is an ABC, you cannot create an instance of this class. """ def __init__(self, include_proper_motion: bool = True): """ :param include_proper_motion: A flag indicating that proper motion should be applied to query results from this catalog """ self.include_proper_motion: bool = include_proper_motion """ Apply proper motion to queried star locations to get the location at the requested time """
[docs] @abstractmethod def query_catalog(self, ids: Optional[Iterable[Any]] = None, min_ra: float = 0, max_ra: float = 360, min_dec: float = -90, max_dec: float = 90, min_mag: float = -4, max_mag: float = 20, search_center: Optional[Sequence[float] | DOUBLE_ARRAY] = None, search_radius: Optional[float] = None, new_epoch: Optional[Union[datetime, float]] = None) -> pd.DataFrame: """ This method queries stars from the catalog that meet specified constraints and returns them as a DataFrame with columns of :attr:`.GIANT_COLUMNS`. Stars can either be queried by ID directly or by right ascension/declination/magnitude. You cannot filter using both with this method. If :attr:`apply_proper_motion` is ``True`` then this will shift the stars to the new epoch input by the user (``new_epoch``) using proper motion. :param ids: A sequence of star ids to retrieve from the catalog. What these ids are vary from catalog to catalog so see the catalog documentation for details. :param min_ra: The minimum ra bound to query stars from in degrees :param max_ra: The maximum ra bound to query stars from in degrees :param min_dec: The minimum declination to query stars from in degrees :param max_dec: The maximum declination to query stars from in degrees :param min_mag: The minimum magnitude to query stars from. Recall that magnitude is inverse (so lower magnitude is a dimmer star) :param max_mag: The maximum magnitude to query stars from. Recall that magnitude is inverse (so higher magnitude is a dimmer star) :param search_center: The center of a search cone as a ra/dec pair. :param search_radius: The radius about the center of the search cone :param new_epoch: The epoch to translate the stars to using proper motion if :attr:`apply_proper_motion` is turned on :return: A Pandas dataframe with columns :attr:`GIANT_COLUMNS`. """ pass
[docs] def get_stars_directions_and_pixels(self: 'Catalog', image: OpNavImage, model: CameraModel, max_mag: float, min_mag: float = -4, image_number: int = 0) -> tuple[pd.DataFrame, np.ndarray, np.ndarray, np.ndarray]: """ This function produces the visible stars in an image, including their records, their inertial unit vectors, and their pixel locations. The function queries the catalog using information contained in the OpNavImage input and the min/max mag inputs. Important attributes of the OpNavImage are `observation_date`, `rotation_inertial_to_camera`, `temperature`, `position`, and `velocity`. The function corrects the catalog unit vectors for parallax and for stellar aberration. :param image: The OpNavImage used to specify metadata about the camera :param model: The camera model used to project unit vectors onto the image :param max_mag: the maximum magnitude star to query from the catalog :param min_mag: the minimum magnitude star to query from the catalog :param image_number: The number of the image being processed :returns: A tuple containing the star records as a pandas DataFrame, the star inertial unit vectors (corrected for aberration and parallax), and the pixels the stars project to """ # get the ra/dec of the z axis of the camera in the inertial frame ra, dec = unit_to_radec(image.rotation_inertial_to_camera.matrix[-1]) # query the star catalog for stars in the field of view stars = self.query_catalog(search_center=(float(np.rad2deg(ra)), float(np.rad2deg(dec))), search_radius=model.field_of_view, new_epoch=image.observation_date, max_mag=max_mag, min_mag=min_mag) # convert the star locations into unit vectors in the inertial frame ra_rad = np.deg2rad(stars['ra'].to_numpy()) dec_rad =np.deg2rad(stars['dec'].to_numpy()) catalog_unit_vectors = radec_to_unit(ra_rad, dec_rad) # correct the unit vectors for parallax using the distance attribute of the star records and the camera inertial # location catalog_points = catalog_unit_vectors * stars['distance'].to_numpy() camera2stars_inertial = catalog_points - image.position.reshape(3, 1) # correct the stellar aberration camera2stars_inertial = correct_stellar_aberration(camera2stars_inertial, image.velocity) # form the corrected unit vectors camera2stars_inertial /= np.linalg.norm(camera2stars_inertial, axis=0, keepdims=True) # rotate the unit vectors into the camera frame rot2camera = image.rotation_inertial_to_camera.matrix catalog_unit_vectors_camera = rot2camera @ camera2stars_inertial # store the inertial corrected unit vectors and the projected image locations return (stars, camera2stars_inertial, catalog_unit_vectors_camera, model.project_onto_image(catalog_unit_vectors_camera, temperature=image.temperature, image=image_number))
@classmethod def __subclasshook__(cls, other: type) -> bool: if cls is Catalog: return hasattr(other, 'query_catalog') return NotImplemented