# Finding stars that would be visible from satellite

I'm working on a mock image of a picture taken from a satellite (like ISS). Lets say I have a camera on ISS pointing in the direction of velocity (I have this velocity vector defined in ITRF and EME2000 frames) with FoV given in degrees (for example 2deg x 3deg) with its roll angle defined in such a way that longer side of FoV is parallel to the Earth surface. I have a catalog with stars and their positions in right ascension and declination, but how do I know which of them would be in my FoV? I know that knowing RA and DEC of the center of my image I can transform any RADEC to standard coordinates like this:

\begin{align} ξ&=\frac{\sin(α−A)}{\sin{D}\tanδ+\cos{D}\cos(α−A)} \\ \\ η&=\frac{\tanδ−\tan{D}\cos(α−A)}{\tan{D}\tanδ+\cos(α−A)} \end{align} where A is right ascension of the center, D is declination of the center. Problem is I don't know how to find RADEC of the center of my image. Is transforming EME2000 (XYZ) to ICRF (RADEC) just a transformation from cartesian to spherical coordinates? And moreover, if I had ξ and η of every star how do I know if they are in my FoV?

• Do you need this solution generally or do you need it one time and could get your mock image from an application like stellarium? Mind that looking in the same direction from Earth without atmosphere is not different than from Earth orbit when it comes to stars. Stellarium allows to define specific optics and camera ships to allow you simulate the FOV directly - useful for and used by astrophotographers. Commented Feb 27 at 9:48
• Unfortunately I need this generally. I need a way, preferably in Python, to supply rectangular FoV in degrees, RADEC of center, and a catalog with stars and get every visible star and theirs position on the image Commented Feb 27 at 12:46
• sounds like nav-cam :) As stellarium draws the FOV for any optics of your choice, and allows configuration, you might find an appropriate answer in its sources: github.com/Stellarium/stellarium/tree/master/src/core - in principle it's just a coordinate transform Commented Feb 27 at 12:52
• The interesting part is that the boundaries of the rectangle do not correspond to a single degree value in spherical coordinates, but need to be desribed by a function. Commented Feb 27 at 12:59
• @jlipinski, how do you define the roll angle of the FOV? Presumably your detector is rolled at some arbitrary angle with respect to the North pole right? Commented Feb 28 at 22:32

Here is my attempt to accomplish this using Astropy's Working with Earth Satellites Using Astropy Coordinates example, in the hopes that it will at least be something to check against / compare with.

To find the center of the FOV for a camera pointing along the velocity vector of the ISS, I first use the TLE representation of its orbit to find the position/velocity in the TEME reference frame, and then I convert those TEME coordinates to ICRF and isolate the velocity vector.

Once I have the center of the FOV, I use astroquery to find the stars in the Hipparcos catalog within the FOV rectangle. A limitation of this code right now is that it does not allow the FOV to be rolled with respect to the North pole.

import numpy as np
import matplotlib.pyplot as plt
import sgp4.api
import astropy.time
import astropy.units as u
import astropy.coordinates
import astroquery.vizier

# Define the time of the observation
time = astropy.time.Time("2024-02-26")

# Define the height and width of the FOV
height_fov = 2 * u.deg
width_fov = 3 * u.deg

# Initialize the ISS TLE representation
satellite = sgp4.api.Satrec.twoline2rv(
"1 25544U 98067A   24058.08023156  .00024246  00000-0  44042-3 0  9999",
"2 25544  51.6420 145.9979 0005776 297.9045 125.0132 15.49405637441327",
)

# Compute the ISS's location/velocity in the TEME coordinate system
err, teme_p, teme_v = satellite.sgp4(time.jd1, time.jd2)
teme_p = astropy.coordinates.CartesianRepresentation(teme_p * u.km)
teme_v = astropy.coordinates.CartesianDifferential(teme_v * u.km / u.s)
teme = astropy.coordinates.TEME(
teme_p.with_differentials(teme_v),
obstime=time,
)

# Transform the ISS's location and velocity into the ICRS coordinate system
icrs = teme.transform_to(astropy.coordinates.ICRS())

# Isolate the velocity vector and express in terms of ICRS
fov_center = astropy.coordinates.ICRS(icrs.velocity.to_cartesian())

# Use the Hipparcos catalog to find stars within this FOV
query_result = astroquery.vizier.Vizier.query_region(
coordinates=fov_center,
height=height_fov,
width=width_fov,
catalog=["Hipparcos"],
)[0]

# Isolate the right ascension, declination, apparent magnitude,
# and Hipparcos ID of each star within the FOV
ra = query_result["RAICRS"]
dec = query_result["DEICRS"]
mag = query_result["Vmag"]
id = query_result["HIP"]

# Plot the stars
fig, ax = plt.subplots()
scatter = ax.scatter(ra, dec, s=np.square(mag/-2.5 + 5))
handles, labels = scatter.legend_elements(
prop="sizes",
func=lambda x: -2.5 * (np.sqrt(x) - 5),
)
legend2 = ax.legend(handles, labels, title="mag")
ax.set_xlabel(f"ICRS right ascension ({ra.unit})")
ax.set_ylabel(f"ICRS declination ({dec.unit})")

# Annotate each star with its Hipparcos ID
for i, _ in enumerate(id):
ax.annotate(
text=f"  {id[i]}",
xy=(ra[i], dec[i]),
fontsize=7,
ha="left",
va="center",
)


Here is a Colab Notebook with this code in case anyone wants to easily run this for themselves.

• Thank you very much for contribution, but that doesn't solve the bigger problem - how to know if a star is in this FoV. Commented Feb 27 at 8:16
• @jlipinski, I've edited the question to solve the bigger problem a little better. Let me know what you think about the roll issue. Commented Feb 28 at 22:58
• This looks almost like what I want, but unfortunately again by my fault there is a small problem. I forgot to define roll angle in my question. Your answer seems to be right but only if my FoV is aligned with ICRS axes which not always would be a case as satellites tend to rotate in their own way or don't rotate at all. Commented Feb 29 at 8:30
• Determining if a star lies within a rotated, warped quadrilateral amounts to solving a point-in-polygon problem. Are you amenable to using a computational geometry library such as Shapely to make this easier? Commented Feb 29 at 8:51
• Anything that can be done in Pytohn Commented Feb 29 at 9:36