Source code for giant.stellar_opnav.visualizers.show_outliers

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
from matplotlib.figure import Figure

from giant.stellar_opnav.stellar_class import StellarOpNav



[docs] class OutlierCallback: """ The class is used to represent an outlier shown to the user for review via the function :func:`show_outlier` and to store the user's choice whether or not to remove the outlier from the matched star pairs. This typically is not used by the user directly. See :meth:`~.StellarOpNav.review_residuals` or :func:`show_outlier` instead. """ def __init__(self, outlier_number: int, image_number: int, centroid: np.ndarray, plot: Figure): """ :param outlier_number: The index of the outlier in the ``matched_`` properties of the :class:`StellarOpNav` class :param image_number: The index of the image in the :attr:`camera` attribute of a :class:`.StellarOpNav` instance where the outlier represented by :class:`OutlierCallback` was found :param centroid: The pixel coordinates of the outlier in the image :param plot: The plot of the outlier """ self.outlier_number: int = outlier_number """ The number of the outlier in the image """ self.image_number: int = image_number """ Image number """ self.centroid: np.ndarray = centroid """ Observed location """ self.plot: Figure = plot """ The plot which shows the outlier in question """ self.removed: bool = False """ A flag specifying whether the outlier has been removed by the user """
[docs] def remove(self, _): """ This method sets the removed flag to 1 and closes the plot. """ self.removed = True print('You have Removed Star {} ({:.2f}, {:.2f}) from Consideration in Image {}'.format(self.outlier_number, *self.centroid, self.image_number)) plt.close(self.plot)
[docs] def keep(self, _): """ This method closes the plot. """ plt.close(self.plot)
[docs] def show_outlier(sopnav: StellarOpNav, index: int, image_num: int, residuals: np.ndarray) -> OutlierCallback: """ This function generates a figure for a specified outlier in the given image number in ``sopnav``. In the generated figure the matched catalog projected star location is shown with one marker, and the matched image point of interest is shown with another. In addition, a vector is drawn indicating the residual for the matched star pair. You must have called :meth:`~.StellarOpNav.id_stars` at least once before calling this function. :param sopnav: The :class:`.StellarOpNav` instance containing the star identification results :param index: The index of the outlier :param image_num: The index of the image in the :attr:`.StellarOpNav.camera` attribute :param residuals: np.ndarray of the residuals between the matched catalog projected star locations and the matched image points of interest for the given image number in the :attr:`.StellarOpNav.camera` attribute """ w = 10 # image zoom window size...num pixels to left and right of centroid cat_locations = sopnav.matched_catalog_image_points[image_num] outlier_image = sopnav.camera.images[image_num] meip = sopnav.matched_extracted_image_points[image_num] assert meip is not None and cat_locations is not None centroid: np.ndarray = meip[:, index] c0: float = float(centroid[1]) c1: float = float(centroid[0]) outlier_fig = plt.figure() a = plt.gca() a.imshow(np.log(outlier_image.astype(np.float64)), cmap='gray', interpolation='none') a.scatter(*cat_locations[:, index], color='none', edgecolors='red', linewidths=1, label='Catalog') a.scatter(c1, c0, color='none', edgecolors='green', linewidths=1, label='Centroid') a.text(c1 + 5, c0 - 5, str(np.round(residuals[:, index], 2).astype(str)), color="yellow", fontsize=8) a.text(c1 - 5, c0 - 5, str((str(np.round(c1)), str(np.round(c0)))), color='green', fontsize=8) a.quiver(c1, c0, residuals[0, index], residuals[1, index], angles='xy', scale_units='xy', scale=1 / 200, color='yellow', label='Residual') a.set_xlim((c1 - w), (c1 + w)) a.set_ylim((c0 - w), (c0 + w)) a.invert_yaxis() a.set_title('Potential Outliers: Image {0}'.format(image_num)) a.legend().set_draggable(True) ax1 = plt.axes((0.15, 0.1, .1, .05)) ax2 = plt.axes((0.75, 0.1, .1, .05)) callback = OutlierCallback(index, image_num, centroid, outlier_fig) b1 = Button(ax1, 'Remove') b1.on_clicked(callback.remove) b2 = Button(ax2, 'Keep') b2.on_clicked(callback.keep) plt.show() return callback