Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

v1 — Analytical revisit climatology

Where on Earth, and how often, could each sensor have imaged the surface — independent of what’s actually in the catalog?

Goal

For every pixel of a 0.1° global grid and each sensor in scope, compute the theoretical overpass cadence purely from orbit propagation + swath geometry. No catalog scan, no STAC, no pixel reads.

Question answered

“How many times in [t0,t1][t_0, t_1] does a satellite with this orbit and swath cross over this pixel?”

Useful as:

  1. The ceiling the data-driven stages get compared against — missing scenes in v2 = catalog gaps, processing failures, off-nadir tasking limits, etc.
  2. A standalone product for users who need “max possible cadence” regardless of cloud / catalog status (mission planning, feasibility studies).

Scope

Algorithm

For each sensor:

  1. Acquire TLEs for every platform in the constellation, sampled at weekly cadence over the window (orbits drift; one TLE per year is too coarse). Source: CelesTrak or Space-Track.
  2. Propagate with skyfield (or sgp4) at a fixed time step Δt (60 s is fine — at 7 km/s the satellite moves ~420 km/step, finer than the swath width for any of these sensors).
  3. Project ground track + swath onto the WGS84 grid:
    • Compute nadir lat/lon at each step.
    • Inflate to a cross-track swath polygon using the sensor’s swath width (S2: 290 km, L8/9: 185 km, MODIS: 2330 km, VIIRS: 3060 km).
    • Rasterise the swath polygon to the grid → boolean mask of cells touched at this timestep.
  4. Tally per cell: increment overpasses[lat, lon, sensor, month] for every cell touched.
  5. Gap statistics: for each cell, derive mean_gap_days and p95_gap_days from the timestamps of overpasses in that cell.

Architecture

This stage is intentionally library-light. No geocatalog, no geotoolz. Single notebook + small helper module:

projects/satellite_climatology/
└── src/satellite_climatology/
    ├── grid.py        # global Zarr schema + grid helpers (shared)
    ├── sensors.py     # platform → swath / inclination / TLE source
    └── analytical.py  # propagate_and_rasterise(sensor, t0, t1) -> xr.Dataset

The one place a repo could be used:

Output

Writes these three bands of the shared Zarr:

overpasses             (sensor, time, lat, lon) int16
mean_gap_days          (sensor, time, lat, lon) float32
p95_gap_days           (sensor, time, lat, lon) float32

Compute budget

Per sensor:

Memory: peak ~1 GB (grid + accumulator).

UI integration

The Zarr is loaded by the dashboard / notebook directly. UI controls:

The whole-globe raster is rendered as a tile layer (leafmap add_raster or deck.gl BitmapLayer after a quick TiTiler tile).

Risks & open questions

Acceptance

Out of scope