<p>Here is my attempt to accomplish this using Astropy's <a href="https://docs.astropy.org/en/stable/coordinates/satellites.html" rel="nofollow noreferrer">Working with Earth Satellites Using Astropy Coordinates</a> example, in the hopes that it will at least be something to check against / compare with.</p>
<p>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.</p>
<p>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.</p>
<pre><code>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(&quot;2024-02-26&quot;)

# 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(
    &quot;1 25544U 98067A   24058.08023156  .00024246  00000-0  44042-3 0  9999&quot;,
    &quot;2 25544  51.6420 145.9979 0005776 297.9045 125.0132 15.49405637441327&quot;,
)

# 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=[&quot;Hipparcos&quot;],
)[0]

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

# 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=&quot;sizes&quot;,
    func=lambda x: -2.5 * (np.sqrt(x) - 5),
)
legend2 = ax.legend(handles, labels, title=&quot;mag&quot;)
ax.set_xlabel(f&quot;ICRS right ascension ({ra.unit})&quot;)
ax.set_ylabel(f&quot;ICRS declination ({dec.unit})&quot;)

# Annotate each star with its Hipparcos ID
for i, _ in enumerate(id):
  ax.annotate(
      text=f&quot;  {id[i]}&quot;,
      xy=(ra[i], dec[i]),
      fontsize=7,
      ha=&quot;left&quot;,
      va=&quot;center&quot;,
  )
</code></pre>
<p><a href="https://i.sstatic.net/oUrBF.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/oUrBF.png" alt="FOV" /></a></p>
<p>Here is a <a href="https://colab.research.google.com/drive/1fOLfbM_880fF7Cg2f0meaSNUacrLxO-O?usp=sharing" rel="nofollow noreferrer">Colab Notebook</a> with this code in case anyone wants to easily run this for themselves.</p>

CC BY-SA 4.0
2024-02-27T08:16:37.827Z
Thank you very much for contribution, but that doesn't solve the bigger problem - how to know if a star is in this FoV.
jlipinski
CC BY-SA 4.0
2024-02-28T22:58:36.493Z
@jlipinski, I've edited the question to solve the bigger problem a little better. Let me know what you think about the roll issue.
Roy Smart
CC BY-SA 4.0
2024-02-29T08:30:32.267Z
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.
jlipinski
CC BY-SA 4.0
2024-02-29T08:51:28.487Z
Determining if a star lies within a rotated, warped quadrilateral amounts to solving a [point-in-polygon problem](https://en.wikipedia.org/wiki/Point_in_polygon). Are you amenable to using a computational geometry library such as [Shapely](https://shapely.readthedocs.io/en/stable/manual.html) to make this easier?
Roy Smart
CC BY-SA 4.0
2024-02-29T09:36:17.390Z
Anything that can be done in Pytohn
jlipinski
CC BY-SA 4.0
2024-02-27T05:10:47.810Z
2024-02-28T23:24:55.143Z
2024-02-28T23:24:55.143Z
Roy Smart
<p>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:</p>
<p><span class="math-container">$$
\begin{align}
ξ&amp;=\frac{\sin(α−A)}{\sin{D}\tanδ+\cos{D}\cos(α−A)} \\
\\
η&amp;=\frac{\tanδ−\tan{D}\cos(α−A)}{\tan{D}\tanδ+\cos(α−A)}
\end{align}
$$</span>
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?</p>

CC BY-SA 4.0
2024-02-27T09:48:20.847Z
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.
planetmaker
CC BY-SA 4.0
2024-02-27T12:46:22.627Z
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
jlipinski
CC BY-SA 4.0
2024-02-27T12:52:54.193Z
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: https://github.com/Stellarium/stellarium/tree/master/src/core - in principle it's just a coordinate transform
planetmaker
CC BY-SA 4.0
2024-02-27T12:59:23.120Z
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.
planetmaker
CC BY-SA 4.0
2024-02-28T22:32:15.287Z
@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?
Roy Smart
CC BY-SA 4.0
2024-02-29T08:24:42.137Z
I'll edit roll angle into question, but the best solution would be to be able to define roll angle independently. For example ISS' underside is always facing Earth so a stationary camera mounted on ISS would also be oriented the same way, lets say longer side of FOV is parallel to Earth surface. So in ICRS roll angle would be changing  - depending on the position of primary satellite and hour angle of center of FoV
jlipinski
<photography><positional-astronomy><frame-of-reference><spherical-astronomy>
Finding stars that would be visible from satellite
jlipinski
# Finding stars that would be visible from satellite

(Asked by: username_0 on 2024-02-23)

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?

**Tags:** photography, positional-astronomy, frame-of-reference, spherical-astronomy

> **Comments:**
> **username_1**: 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.  
> **username_0**: 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  
> **username_1**: 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: https://github.com/Stellarium/stellarium/tree/master/src/core - in principle it's just a coordinate transform  
> **username_1**: 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.  
> **username_2**: @username_0, 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?  
> **username_0**: I'll edit roll angle into question, but the best solution would be to be able to define roll angle independently. For example ISS' underside is always facing Earth so a stationary camera mounted on ISS would also be oriented the same way, lets say longer side of FOV is parallel to Earth surface. So in ICRS roll angle would be changing  - depending on the position of primary satellite and hour angle of center of FoV  

---

## 1 answers

### Answer by username_2 on 2024-02-27. Score: 2

Here is my attempt to accomplish this using Astropy's [Working with Earth Satellites Using Astropy Coordinates](https://docs.astropy.org/en/stable/coordinates/satellites.html) 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",
  )

```

[![FOV](https://i.sstatic.net/oUrBF.png)](https://i.sstatic.net/oUrBF.png)

Here is a [Colab Notebook](https://colab.research.google.com/drive/1fOLfbM_880fF7Cg2f0meaSNUacrLxO-O?usp=sharing) with this code in case anyone wants to easily run this for themselves.

> **Comments:**
> **username_0**: Thank you very much for contribution, but that doesn't solve the bigger problem - how to know if a star is in this FoV.  
> **username_2**: @username_0, I've edited the question to solve the bigger problem a little better. Let me know what you think about the roll issue.  
> **username_0**: 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.  
> **username_2**: Determining if a star lies within a rotated, warped quadrilateral amounts to solving a [point-in-polygon problem](https://en.wikipedia.org/wiki/Point_in_polygon). Are you amenable to using a computational geometry library such as [Shapely](https://shapely.readthedocs.io/en/stable/manual.html) to make this easier?  
> **username_0**: Anything that can be done in Pytohn  

---

