Source code for hsr4hci.coordinates

"""
Methods for dealing with coordinates.
"""

# -----------------------------------------------------------------------------
# IMPORTS
# -----------------------------------------------------------------------------

from typing import Tuple

import math

from astropy.units import Quantity


# -----------------------------------------------------------------------------
# FUNCTION DEFINITIONS
# -----------------------------------------------------------------------------

[docs]def get_center(frame_size: Tuple[int, int]) -> Tuple[float, float]: """ Using the frame size of an image, determine the precise position of its center in the usual coordinate system that we place on our data: The *center* of the pixel in the bottom left corner of the image is defined as (0, 0), so the bottom left corner of the image is located at (-0.5, -0.5). This function is essentially a simplified port of the corresponding PynPoint function :py:func:`pynpoint.util.image.center_subpixel()`. Args: frame_size: A tuple of integers `(x_size, y_size)` specifying the size of the images (in pixels). Returns: A tuple of floats, `(center_x, center_y)` containing the position of the center of the image. """ return frame_size[0] / 2 - 0.5, frame_size[1] / 2 - 0.5
[docs]def polar2cartesian( separation: Quantity, angle: Quantity, frame_size: Tuple[int, int], ) -> Tuple[float, float]: """ Convert a position in astronomical polar coordinates to Cartesian coordinates (in pixels). Args: separation: Separation from the center (as a ``Quantity`` object that can be converted to pixels). angle: Angle, measured from the up = North direction (this corresponds to a -90ยฐ offset compared to "normal" polar coordinates), as a ``Quantity`` object that can be converted to degrees or radian. frame_size: A 2-tuple `(x_size, y_size)` of integers specifying the size of the frame that we are working with. Returns: A 2-tuple `(x, y)` containing the Cartesian representation of the position specified by the `(separation, angle)` tuple. The Cartesian representation uses the astropy convention for the position of the origin, and the numpy convention for the order of the dimensions. """ # Convert separation and angle to pixel / radian and get raw values rho = separation.to('pixel').value phi = angle.to('radian').value # Convert from astronomical to mathematical polar coordinates phi += math.pi / 2 # Get coordinates of image center center = get_center(frame_size=frame_size) # Convert from polar to Cartesian coordinates x = center[0] + rho * math.cos(phi) y = center[1] + rho * math.sin(phi) return x, y
[docs]def cartesian2polar( position: Tuple[float, float], frame_size: Tuple[int, int], ) -> Tuple[Quantity, Quantity]: """ Convert a position in Cartesian coordinates (in pixels) to astronomical polar coordinates. Args: position: A tuple `(x, y)` containing a position in Cartesian coordinates. frame_size: A 2-tuple `(width, height)` of integers specifying the size of the frame that we are working with. Returns: A 2-tuple `(separation, angle)`, where the `separation` is a ``Quantity`` in pixels, and `angle` is a ``Quantity`` in radian. The `angle` uses the astronomical convention for polar coordinates, that is, 0 is "up", not "right" (unlike in mathematical polar coordinates). """ # Get coordinates of image center center = get_center(frame_size=frame_size) # Compute separation and the angle separation = math.sqrt( (position[0] - center[0]) ** 2 + (position[1] - center[1]) ** 2 ) angle = math.atan2(position[1] - center[1], position[0] - center[0]) # Convert from mathematical to astronomical polar coordinates; constrain # the polar angle to the interval [0, 2pi]. angle -= math.pi / 2 angle = math.fmod(angle, 2 * math.pi) return Quantity(separation, 'pixel'), Quantity(angle, 'radian')