Search, download, process, and plot geostationary GOES ABI Level-2P sea surface temperature from the NASA Earthdata PO.DAAC GHRSST archive.

Overview

The directory name follows the repo's geos convention, but the data source is GOES — the NOAA geostationary satellite series (GOES-East / GOES-West) — not the NASA GEOS model. The pipeline mirrors snpp: search NASA Earthdata/CMR via earthaccess, download raw L2P granules idempotently, process them into analysis-ready NetCDF (Kelvin→Celsius, recommended-quality mask, decoded day/night masks, and derived lat/lon from the GOES fixed grid), and optionally render PNG SST maps.

geos_sst.py is the search/download/process/plot driver. regrid_geos_sst.py resamples processed or raw granules onto a regular grid (same machinery as SNPP, after ensure_lat_lon). granule_footprints.py writes the colocate lookup table. Because ABI granules store data on the geostationary fixed grid, processing derives lat/lon from the CF geostationary projection with pyproj when they are not already present.

Default collections (the current alias) are the active GOES-East and GOES-West GHRSST L2P products:

Alias Collections
current (default) ABI_G19-STAR-L2P-v3.0, G18-ABI-L2P-ACSPO-v2.90
east / goes-east ABI_G19-STAR-L2P-v3.0
west / goes-west G18-ABI-L2P-ACSPO-v2.90
east-all ABI_G19-STAR-L2P-v3.0, ABI_G16-STAR-L2P-v2.70
west-all G18-ABI-L2P-ACSPO-v2.90, ABI_G17-STAR-L2P-v2.71
legacy ABI_G16-STAR-L2P-v2.70, ABI_G17-STAR-L2P-v2.71
all current + legacy G16/G17

Outputs land under /spray/geos by default (overridable with --out-root).

Installation & dependencies

Core dependencies: earthaccess, xarray, numpy, a NetCDF writer (netCDF4 or h5netcdf), and pyproj (to derive lat/lon from the GOES fixed grid). tqdm is used for progress bars when present. From the repo root:

python -m pip install -e ".[all]"       # everything, or:
python -m pip install -e ".[plot]"
  • NASA Earthdata credentials are required for downloads. earthaccess reads them from ~/.netrc:

text machine urs.earthdata.nasa.gov login <username> password <password>

  • The plot extra installs cartopy, used for the coastline/gridline map preview (--plot / --plot-only). Without cartopy, plotting falls back to a plain lon/lat axes via matplotlib.

Entry points & scripts

Console script Module Purpose
odsl-geos-sst geos.geos_sst:main Search, download, process, and plot GOES ABI L2P SST
odsl-geos-regrid geos.regrid_geos_sst:main Regrid a processed/raw granule (wraps SNPP regrid after ensure_lat_lon)
odsl-geos-footprints geos.granule_footprints:main Incremental parquet of processed granules for colocate

--start and --end are required on odsl-geos-sst (the GOES archive is continuous, so an implicit “today” window is the wrong default). Regrid defaults to /spray/geos/regridded when --output / --output-dir are omitted. Footprints default to /spray/geos/footprints/geos_granule_footprints.parquet (odsl-colocate-refresh --targets geos). The super-subsetter source name is "geos" (--geos-root).

Each script also runs directly (python geos/geos_sst.py …); a repo-root sys.path bootstrap makes the shared common package importable either way.

Usage

Search a date range and bounding box (west south east north) across both current collections, download, and process to /spray/geos:

python geos/geos_sst.py \
    --start 2026-06-10 \
    --end 2026-06-10 \
    --collection current \
    --bbox -98 18 -80 31

Process and render SST map previews in one pass:

python geos/geos_sst.py \
    --start 2026-06-10 --end 2026-06-10 \
    --collection east \
    --bbox -98 18 -80 31 \
    --plot --max-plots 3

Common variations:

# Search + write manifests only (no download)
python geos/geos_sst.py --start 2026-06-10 --end 2026-06-10 \
    --bbox -98 18 -80 31 --manifest-only

# Download raw granules but skip processing
python geos/geos_sst.py --start 2026-06-10 --end 2026-06-10 --download-only

# Process existing raw files only
python geos/geos_sst.py --process-only /spray/geos/raw/ABI_G19-STAR-L2P-v3.0/2026/06/10/example.nc

# Plot existing processed/raw files only, with day-only pixels and a fixed scale
python geos/geos_sst.py \
    --plot-only /spray/geos/processed/ABI_G19-STAR-L2P-v3.0/2026/06/10/example_processed.nc \
    --bbox -98 18 -80 31 \
    --plot-day-night day --plot-vmin 20 --plot-vmax 32

Other flags: --variables (comma-separated source vars or all), --quality-min / --no-quality-mask, --no-bbox-subset, --no-geolocation (skip deriving lat/lon unless a bbox needs it), --plot-variable, --plot-all-quality, --plot-cmap, the --overwrite-* flags, --provider, and --auth-strategy.

Output layout

/spray/geos/
├── manifests/
│   ├── <collection|multi>_<start>_<end>_manifest.csv
│   └── <collection|multi>_<start>_<end>_manifest.json
├── raw/
│   └── {collection}/YYYY/MM/DD/*.nc
├── processed/
│   └── {collection}/YYYY/MM/DD/*_processed.nc
├── regridded/             # default odsl-geos-regrid outputs
├── footprints/
│   └── geos_granule_footprints.parquet
└── plots/
    └── {collection}/YYYY/MM/DD/*_sst.png

Raw files, processed files, and plots are each skipped when already present unless the matching --overwrite-downloads, --overwrite-processed, or --overwrite-plots flag is set.

SST processing details

Processed files retain a selected subset of source variables (or all with --variables all) and add these derived fields:

Variable Description
lat, lon Derived from the CF geostationary projection via pyproj when absent from the source
sst_celsius sea_surface_temperature converted from Kelvin (− 273.15) to °C
recommended_quality int8 mask where quality_level >= 5 (default --quality-min; disable with --no-quality-mask)
is_day Daytime pixel mask decoded from the l2p_flags CF bitmask
is_night Nighttime pixel mask decoded from l2p_flags (falls back to ~is_day when only a day flag is present)

Day/night masks are decoded from the flag_masks/flag_values + flag_meanings attributes of l2p_flags. When --bbox is supplied, processed files are subset to that box unless --no-bbox-subset is given (bbox subsetting always derives geolocation first). Plots default to recommended-quality pixels only; use --plot-all-quality to show every level.

Shared code

This module was refactored to import shared helpers from the repo-root common package so the GEOS and SNPP pipelines stay in sync:

  • common.log — timestamped log() to stderr
  • common.earthdatanormalize_cmr_time, split_antimeridian_bbox, filename_from_url, date_parts, safe_token, existing_netcdf_files
  • common.flags — CF flag-decode helpers (_as_list, _normalize_flag_name)
  • common.datasetclear_encodings
  • common.cliparse_variables
  • common.footprints — incremental SST granule index (odsl-geos-footprints)

The script prepends the repo root to sys.path so it runs both as an installed console script and directly.