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.
earthaccessreads them from~/.netrc:
text
machine urs.earthdata.nasa.gov login <username> password <password>
- The
plotextra installscartopy, 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— timestampedlog()to stderrcommon.earthdata—normalize_cmr_time,split_antimeridian_bbox,filename_from_url,date_parts,safe_token,existing_netcdf_filescommon.flags— CF flag-decode helpers (_as_list,_normalize_flag_name)common.dataset—clear_encodingscommon.cli—parse_variablescommon.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.
Related links
../common— shared regridding, Earthdata, and footprint utilities../snpp— the parallel Suomi-NPP VIIRS SST pipeline../colocate— matchups against the GOES footprint parquet../README.md— repository conventions and domain gotchas- GOES-19 East: https://podaac.jpl.nasa.gov/dataset/ABI_G19-STAR-L2P-v3.0
- GOES-18 West: https://podaac.jpl.nasa.gov/dataset/G18-ABI-L2P-ACSPO-v2.90
- NOAA CoastWatch ABI SST: https://coastwatch.noaa.gov/cwn/products/acspo-global-sst-abi.html