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 midpoint

  • sat_alt: satellite altitude angle (degrees) at epoch

  • sat_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 observation

  • revisit: duration since the prior observation (note: the first observation has NaT for 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()
../_images/0fabe8b983d456e2aa9f919453535c647553d46524edd22a55297159e6423798.png