Source code for astra.utils.optics
"""
Pure optics math shared across device-based and FITS-header-based code paths.
`paired_devices.py` derives plate scale from live Alpaca `Camera`/`Telescope`
device properties, while `pointer.py` derives it from FITS header metadata
(`XPIXSZ`/`FOCALLEN`). Both then need the same downstream math (plate scale,
field of view, FWHM in pixels), so that math lives here as plain functions
over floats/arrays with no device or FITS dependencies.
"""
from typing import Union
import numpy as np
[docs]
def plate_scale(
pixel_size: Union[float, np.ndarray], focal_length: float
) -> np.ndarray:
"""
Calculate the plate scale in degrees per pixel.
Parameters:
pixel_size: Pixel size in meters. Scalar or array (e.g. [x, y]).
focal_length (float): Focal length in meters.
Returns:
Plate scale in degrees per pixel, same shape as `pixel_size`.
"""
return np.degrees(np.arctan(np.asarray(pixel_size) / focal_length))
[docs]
def field_of_view(
sensor_size: Union[float, np.ndarray], focal_length: float
) -> np.ndarray:
"""
Calculate the field of view spanned by a sensor, without the small-angle
approximation.
Parameters:
sensor_size: Sensor extent in meters. Scalar or array (e.g. [sx, sy]).
focal_length (float): Focal length in meters.
Returns:
Field of view in degrees, same shape as `sensor_size`.
"""
return 2.0 * np.degrees(np.arctan(np.asarray(sensor_size) / (2.0 * focal_length)))
[docs]
def fov_from_plate_scale(
num_pixels: Union[float, np.ndarray], plate_scale_deg_per_pixel: float
) -> np.ndarray:
"""
Calculate field of view from a per-pixel plate scale (small-angle approximation).
Parameters:
num_pixels: Number of pixels along one or more axes.
plate_scale_deg_per_pixel (float): Plate scale in degrees per pixel.
Returns:
Field of view in degrees, same shape as `num_pixels`.
"""
return np.asarray(num_pixels) * plate_scale_deg_per_pixel
[docs]
def fwhm_pixels(plate_scale_deg_per_pixel: float, seeing_arcsec: float = 1) -> float:
"""
Calculate the expected FWHM in pixels for a given atmospheric seeing.
Parameters:
plate_scale_deg_per_pixel (float): Plate scale in degrees per pixel.
seeing_arcsec (float): Atmospheric seeing in arcseconds.
Returns:
float: Expected FWHM in pixels.
"""
plate_scale_arcsec_per_pixel = plate_scale_deg_per_pixel * 3600.0
return seeing_arcsec / plate_scale_arcsec_per_pixel