Collect Observations
This example demonstrates how to use direct function calls of the low-level TAT-C library to collect observations of a surface point. Observations show when a satellite-based instrument can observe the point based on spatial and operational constraints.
First we define the satellites for a mission. In this example we define one satellite (NOAA-20) with a single instrument (Visual/Infrared Imager Radiometer Suite, VIIRS) and an orbit derived from a known two-line element set (TLE). The TLE defines the orbital state at an instant in time which can be used to determine future positions of the satellite. The example TLE below for NOAA-20 was collected from CelesTrak around July 2022.
noaa20_tle = [
"1 43013U 17073A 22195.78278435 .00000038 00000+0 38919-4 0 9996",
"2 43013 98.7169 133.9110 0001202 63.8768 296.2532 14.19561306241107",
]
TAT-C allows several types of orbit specifications, one of which being the TwoLineElements specification which requires the TLE as an argument.
from tatc.schemas import TwoLineElements
noaa20_orbit = TwoLineElements(tle=noaa20_tle)
Next, we define an instrument to perform observations. The most important parameter is the field of regard which sets the view angle from the satellite to the Earth’s surface. The TAT-C utils package contains a function to calculate the field of regard from an instrument’s altitude (834 km) and swath width (3000 km).
from tatc import utils
viirs_for = utils.swath_width_to_field_of_regard(834e3, 3000e3)
print(f"computed field of regard: {viirs_for:.1f} degrees")
computed field of regard: 111.6 degrees
We can pass the field of regard to create an instrument model of VIIRS.
from tatc.schemas import Instrument
viirs = Instrument(name="VIIRS", field_of_regard=viirs_for)
Finally, we can combine the orbit and instrument to define a new satellite.
from tatc.schemas import Satellite
noaa20 = Satellite(name="NOAA 20", orbit=noaa20_orbit, instruments=[viirs])
Next, we define the point of interest to observe using geodetic coordinates.
from tatc.schemas import Point
hoboken = Point(id=0, latitude=40.74259, longitude=-74.02686)
Next, we can identify the starting and ending time of a sample mission period. The starting time is noon UTC on July 14, 2022 and the ending time is 30 days later (noon UTC on August 13, 2022).
from datetime import datetime, timedelta, timezone
start = datetime(year=2022, month=7, day=14, hour=12, tzinfo=timezone.utc)
end = start + timedelta(days=30)
The collect_observations analysis function identifies all of the observation opportunities of a point by a satellite instrument between the starting and ending time. Results are formatted as a flat GeoDataFrame which is similar to a regular pandas DataFrame with a geospatial column labeled geometry. Other columns:
start: observation rise time (or mission start for first observation)end: observation set time (or mission end for last observation)epoch: observation midpointsat_alt: satellite altitude angle (degrees) at epochsat_az: satellite azimuth angle (degrees) at epoch
from tatc.analysis import collect_observations
results = collect_observations(hoboken, noaa20, start, end)
display(results)
| point_id | geometry | satellite | instrument | start | end | epoch | sat_alt | sat_az | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 | VIIRS | 2022-07-14 17:14:31.310369+00:00 | 2022-07-14 17:21:09.157255+00:00 | 2022-07-14 17:17:50.233812+00:00 | 45.832413 | 69.766369 |
| 1 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 | VIIRS | 2022-07-14 18:56:58.849666+00:00 | 2022-07-14 18:59:29.309441+00:00 | 2022-07-14 18:58:14.079553500+00:00 | 22.556721 | 266.369724 |
| 2 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 | VIIRS | 2022-07-15 07:12:52.951632+00:00 | 2022-07-15 07:19:53.364882+00:00 | 2022-07-15 07:16:23.158257+00:00 | 54.469247 | 288.828497 |
| 3 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 | VIIRS | 2022-07-15 16:56:31.366398+00:00 | 2022-07-15 17:01:47.933741+00:00 | 2022-07-15 16:59:09.650069500+00:00 | 31.731119 | 66.726221 |
| 4 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 | VIIRS | 2022-07-15 18:36:30.433195+00:00 | 2022-07-15 18:42:04.442407+00:00 | 2022-07-15 18:39:17.437801+00:00 | 33.133927 | 263.486527 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 75 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 | VIIRS | 2022-08-11 16:50:18.188008+00:00 | 2022-08-11 16:54:52.763667+00:00 | 2022-08-11 16:52:35.475837500+00:00 | 28.098506 | 65.027713 |
| 76 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 | VIIRS | 2022-08-11 18:29:34.474832+00:00 | 2022-08-11 18:35:40.954880+00:00 | 2022-08-11 18:32:37.714856+00:00 | 37.899973 | 263.363098 |
| 77 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 | VIIRS | 2022-08-12 06:47:16.593473+00:00 | 2022-08-12 06:54:45.463780+00:00 | 2022-08-12 06:51:01.028626500+00:00 | 89.184043 | 156.518247 |
| 78 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 | VIIRS | 2022-08-12 18:10:11.765146+00:00 | 2022-08-12 18:17:18.069412+00:00 | 2022-08-12 18:13:44.917279+00:00 | 56.535506 | 261.467055 |
| 79 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 | VIIRS | 2022-08-13 06:28:34.773044+00:00 | 2022-08-13 06:35:48.839408+00:00 | 2022-08-13 06:32:11.806226+00:00 | 61.217019 | 102.685206 |
80 rows × 9 columns
The aggregate_observations function groups observations of points to compute metrics like access and revisit.
access: duration of an observationrevisit: duration since the prior observation (note: the first observation hasNaTfor missing data
from tatc.analysis import aggregate_observations
aggregated_results = aggregate_observations(results)
display(aggregated_results)
| geometry | point_id | satellite | instrument | start | epoch | end | access | revisit | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 | VIIRS | 2022-07-14 17:14:31.310369+00:00 | 2022-07-14 17:17:50.233811968+00:00 | 2022-07-14 17:21:09.157255+00:00 | 0 days 00:06:37.846886 | NaT |
| 1 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 | VIIRS | 2022-07-14 18:56:58.849666+00:00 | 2022-07-14 18:58:14.079553536+00:00 | 2022-07-14 18:59:29.309441+00:00 | 0 days 00:02:30.459775 | 0 days 01:35:49.692411 |
| 2 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 | VIIRS | 2022-07-15 07:12:52.951632+00:00 | 2022-07-15 07:16:23.158256896+00:00 | 2022-07-15 07:19:53.364882+00:00 | 0 days 00:07:00.413250 | 0 days 12:13:23.642191 |
| 3 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 | VIIRS | 2022-07-15 16:56:31.366398+00:00 | 2022-07-15 16:59:09.650069504+00:00 | 2022-07-15 17:01:47.933741+00:00 | 0 days 00:05:16.567343 | 0 days 09:36:38.001516 |
| 4 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 | VIIRS | 2022-07-15 18:36:30.433195+00:00 | 2022-07-15 18:39:17.437800960+00:00 | 2022-07-15 18:42:04.442407+00:00 | 0 days 00:05:34.009212 | 0 days 01:34:42.499454 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 75 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 | VIIRS | 2022-08-11 16:50:18.188008+00:00 | 2022-08-11 16:52:35.475837440+00:00 | 2022-08-11 16:54:52.763667+00:00 | 0 days 00:04:34.575659 | 0 days 09:36:54.523333 |
| 76 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 | VIIRS | 2022-08-11 18:29:34.474832+00:00 | 2022-08-11 18:32:37.714855936+00:00 | 2022-08-11 18:35:40.954880+00:00 | 0 days 00:06:06.480048 | 0 days 01:34:41.711165 |
| 77 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 | VIIRS | 2022-08-12 06:47:16.593473+00:00 | 2022-08-12 06:51:01.028626432+00:00 | 2022-08-12 06:54:45.463780+00:00 | 0 days 00:07:28.870307 | 0 days 12:11:35.638593 |
| 78 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 | VIIRS | 2022-08-12 18:10:11.765146+00:00 | 2022-08-12 18:13:44.917278976+00:00 | 2022-08-12 18:17:18.069412+00:00 | 0 days 00:07:06.304266 | 0 days 11:15:26.301366 |
| 79 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 | VIIRS | 2022-08-13 06:28:34.773044+00:00 | 2022-08-13 06:32:11.806225920+00:00 | 2022-08-13 06:35:48.839408+00:00 | 0 days 00:07:14.066364 | 0 days 12:11:16.703632 |
80 rows × 9 columns
Finally, TAT-C includes a supplemental method reduce_observations to compute descriptive statistics.
from tatc.analysis import reduce_observations
reduced_results = reduce_observations(aggregated_results)
display(reduced_results)
| point_id | geometry | access | revisit | samples | |
|---|---|---|---|---|---|
| 0 | 0 | POINT Z (-74.02686 40.74259 0) | 0 days 00:05:55.491148 | 0 days 08:52:45.040978 | 80 |
The same sequence of operations can be repeated for satellite constellations. For example, the following constellation starts with NOAA-20 as a “template” and arranges 3 satellites in 3 orbital planes following a Walker star geometry.
from tatc.schemas import WalkerConstellation
const = WalkerConstellation(
name="NOAA 20",
orbit=noaa20_orbit,
instruments=[viirs],
number_satellites=3,
number_planes=3,
configuration="star",
)
When using constellations or lists of satellites, use the collect_multi_observations function call. Note that it will collect observations for all defined instruments.
from tatc.analysis import collect_multi_observations
results = collect_multi_observations(hoboken, const, start, end)
display(results)
| point_id | geometry | satellite | instrument | start | end | epoch | sat_alt | sat_az | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 3 | VIIRS | 2022-07-14 14:18:41.843832+00:00 | 2022-07-14 14:25:32.984712+00:00 | 2022-07-14 14:22:07.414272+00:00 | 49.134764 | 99.453987 |
| 1 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 3 | VIIRS | 2022-07-14 16:00:48.305713+00:00 | 2022-07-14 16:03:09.455300+00:00 | 2022-07-14 16:01:58.880506500+00:00 | 22.391592 | 296.411261 |
| 2 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 1 | VIIRS | 2022-07-14 17:14:31.310369+00:00 | 2022-07-14 17:21:09.157255+00:00 | 2022-07-14 17:17:50.233812+00:00 | 45.832413 | 69.766369 |
| 3 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 1 | VIIRS | 2022-07-14 18:56:58.849666+00:00 | 2022-07-14 18:59:29.309441+00:00 | 2022-07-14 18:58:14.079553500+00:00 | 22.556721 | 266.369724 |
| 4 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 2 | VIIRS | 2022-07-14 20:40:17.146080+00:00 | 2022-07-14 20:42:53.973151+00:00 | 2022-07-14 20:41:35.559615500+00:00 | 22.801401 | 63.710155 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 237 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 3 | VIIRS | 2022-08-13 00:58:07.584550+00:00 | 2022-08-13 01:03:35.190820+00:00 | 2022-08-13 01:00:51.387685+00:00 | 32.870653 | 66.168331 |
| 238 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 3 | VIIRS | 2022-08-13 02:38:19.726352+00:00 | 2022-08-13 02:43:41.909195+00:00 | 2022-08-13 02:41:00.817773500+00:00 | 31.910221 | 264.638645 |
| 239 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 1 | VIIRS | 2022-08-13 06:28:34.773044+00:00 | 2022-08-13 06:35:48.839408+00:00 | 2022-08-13 06:32:11.806226+00:00 | 61.217019 | 102.685206 |
| 240 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 2 | VIIRS | 2022-08-13 09:53:07.157574+00:00 | 2022-08-13 09:57:51.075326+00:00 | 2022-08-13 09:55:29.116450+00:00 | 28.416874 | 96.047271 |
| 241 | 0 | POINT Z (-74.02686 40.74259 0) | NOAA 20 2 | VIIRS | 2022-08-13 11:32:45.365663+00:00 | 2022-08-13 11:38:40.975563+00:00 | 2022-08-13 11:35:43.170613+00:00 | 36.746860 | 291.210499 |
242 rows × 9 columns
Similar to the single-satellite case, aggregate_observations adds access and revisit information; however, these metrics are now computed for the aggregate constellation.
aggregated_results = aggregate_observations(results)
display(aggregated_results)
| geometry | point_id | satellite | instrument | start | epoch | end | access | revisit | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 3 | VIIRS | 2022-07-14 14:18:41.843832+00:00 | 2022-07-14 14:22:07.414272+00:00 | 2022-07-14 14:25:32.984712+00:00 | 0 days 00:06:51.140880 | NaT |
| 1 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 3 | VIIRS | 2022-07-14 16:00:48.305713+00:00 | 2022-07-14 16:01:58.880506624+00:00 | 2022-07-14 16:03:09.455300+00:00 | 0 days 00:02:21.149587 | 0 days 01:35:15.321001 |
| 2 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 1 | VIIRS | 2022-07-14 17:14:31.310369+00:00 | 2022-07-14 17:17:50.233811968+00:00 | 2022-07-14 17:21:09.157255+00:00 | 0 days 00:06:37.846886 | 0 days 01:11:21.855069 |
| 3 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 1 | VIIRS | 2022-07-14 18:56:58.849666+00:00 | 2022-07-14 18:58:14.079553536+00:00 | 2022-07-14 18:59:29.309441+00:00 | 0 days 00:02:30.459775 | 0 days 01:35:49.692411 |
| 4 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 2 | VIIRS | 2022-07-14 20:40:17.146080+00:00 | 2022-07-14 20:41:35.559615488+00:00 | 2022-07-14 20:42:53.973151+00:00 | 0 days 00:02:36.827071 | 0 days 01:40:47.836639 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 237 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 3 | VIIRS | 2022-08-13 00:58:07.584550+00:00 | 2022-08-13 01:00:51.387685120+00:00 | 2022-08-13 01:03:35.190820+00:00 | 0 days 00:05:27.606270 | 0 days 03:17:15.434013 |
| 238 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 3 | VIIRS | 2022-08-13 02:38:19.726352+00:00 | 2022-08-13 02:41:00.817773568+00:00 | 2022-08-13 02:43:41.909195+00:00 | 0 days 00:05:22.182843 | 0 days 01:34:44.535532 |
| 239 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 1 | VIIRS | 2022-08-13 06:28:34.773044+00:00 | 2022-08-13 06:32:11.806225920+00:00 | 2022-08-13 06:35:48.839408+00:00 | 0 days 00:07:14.066364 | 0 days 03:44:52.863849 |
| 240 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 2 | VIIRS | 2022-08-13 09:53:07.157574+00:00 | 2022-08-13 09:55:29.116450048+00:00 | 2022-08-13 09:57:51.075326+00:00 | 0 days 00:04:43.917752 | 0 days 03:17:18.318166 |
| 241 | POINT Z (-74.02686 40.74259 0) | 0 | NOAA 20 2 | VIIRS | 2022-08-13 11:32:45.365663+00:00 | 2022-08-13 11:35:43.170612992+00:00 | 2022-08-13 11:38:40.975563+00:00 | 0 days 00:05:55.609900 | 0 days 01:34:54.290337 |
242 rows × 9 columns
Finally, the reduce_observations function computes descriptive statistics for the constellation.
reduced_results = reduce_observations(aggregated_results)
display(reduced_results)
| point_id | geometry | access | revisit | samples | |
|---|---|---|---|---|---|
| 0 | 0 | POINT Z (-74.02686 40.74259 0) | 0 days 00:05:55.520830 | 0 days 02:52:38.353074 | 242 |
The workflow can enable sensitivity analyses, for example, determining how the number of satellites in a Walker star constellation affect mean revisit time.
import numpy as np
n = np.arange(1, 7)
revisit = [
reduce_observations(
aggregate_observations(
collect_multi_observations(
hoboken,
WalkerConstellation(
name="NOAA 20",
orbit=noaa20_orbit,
instruments=[viirs],
number_satellites=i,
number_planes=i,
configuration="star",
),
start,
end,
)
)
)
.iloc[0]
.revisit
/ timedelta(hours=1)
for i in n
]
import matplotlib.pyplot as plt
plt.figure()
plt.plot(n, revisit, ".-")
plt.xlabel("Number Satellites/Planes (Walker Star)")
plt.ylabel("Mean Revisit (hr)")
plt.show()