Search, download, process, and regrid Suomi-NPP VIIRS Level-2P sea surface temperature granules from the NASA Earthdata PO.DAAC GHRSST archive.
Overview
This package targets the active PO.DAAC GHRSST NOAA STAR ACSPO product
VIIRS_NPP-STAR-L2P-v2.80 (the default collection). Each Level-2P swath file
contains both day and night retrievals, with the day/night state encoded in
the CF l2p_flags bitmask.
Two scripts cover the workflow:
snpp_viirs_sst.py— search NASA Earthdata/CMR viaearthaccess, download raw granules idempotently, and process them into smaller, analysis-ready NetCDF files (Kelvin→Celsius, a recommended-quality mask, and decoded day/night masks). Search, download, and processing can each be run in isolation.regrid_snpp_sst.py— resample a processed or raw swath onto a regular lat/lon grid or a regional azimuthal-equidistant cartesian grid, with an optional PNG map preview. Built oncommon.swath_regrid(pyresample).
All outputs land under /spray/snpp by default, overridable with --out-root.
Installation & dependencies
Core dependencies: earthaccess, xarray, numpy, a NetCDF writer
(netCDF4 or h5netcdf), and pyproj + pyresample for regridding. 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,kriging]"
- 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 inregrid_snpp_sst.py --plot. Without it the plot falls back to a plain lon/lat axes. Thekrigingextra (pykrige) enables the kriging regrid method.
Entry points & scripts
| Console script | Module | Purpose |
|---|---|---|
odsl-snpp-sst |
snpp.snpp_viirs_sst:main |
Search, download, and process VIIRS L2P SST |
odsl-snpp-regrid |
snpp.regrid_snpp_sst:main |
Regrid a processed/raw swath and optionally plot |
odsl-snpp-footprints |
snpp.granule_footprints:main |
Incremental parquet of processed granules for colocate |
Footprints default to /spray/snpp/footprints/snpp_granule_footprints.parquet
(odsl-colocate-refresh --targets snpp). Re-running is incremental unless
--rebuild is set.
Each script also runs directly (python snpp/snpp_viirs_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), download, and
process to /spray/snpp:
python snpp/snpp_viirs_sst.py \
--start 2024-01-01 \
--end 2024-01-02 \
--bbox -98 18 -80 31
Common variations:
# Search + write manifests only (no download)
python snpp/snpp_viirs_sst.py --start 2024-01-01 --end 2024-01-02 \
--bbox -98 18 -80 31 --manifest-only
# Download raw granules but skip processing
python snpp/snpp_viirs_sst.py --start 2024-01-01 --end 2024-01-02 --download-only
# Keep full swaths (do not subset processed files to --bbox)
python snpp/snpp_viirs_sst.py --start 2024-01-01 --end 2024-01-02 \
--bbox -98 18 -80 31 --no-bbox-subset
# Keep every source variable; disable the quality mask; re-run overwriting
python snpp/snpp_viirs_sst.py --start 2024-01-01 --end 2024-01-01 \
--variables all --no-quality-mask \
--overwrite-downloads --overwrite-processed
Other flags: --collection (CMR short name, default VIIRS_NPP-STAR-L2P-v2.80),
--provider (default POCLOUD), --max-granules, --quality-min,
--auth-strategy.
Regrid a processed swath onto a 0.02° lat/lon grid with a map preview:
python snpp/regrid_snpp_sst.py \
--input /spray/snpp/processed/VIIRS_NPP-STAR-L2P-v2.80/2024/01/01/example_processed.nc \
--grid-type latlon \
--bbox -98 18 -80 31 \
--resolution-deg 0.02 \
--method gaussian \
--radius-of-influence 15000 \
--smoothing-radius 7500 \
--grid-file /spray/snpp/grids/gulf_002deg.nc \
--plot
Regrid onto a regional 2 km cartesian grid centered on a point:
python snpp/regrid_snpp_sst.py \
--input /spray/snpp/raw/VIIRS_NPP-STAR-L2P-v2.80/2024/01/01/example.nc \
--grid-type cartesian \
--center-lat 25 --center-lon -89 \
--dx-m 2000 --width-m 1500000 --height-m 1100000 \
--method linear \
--grid-file /spray/snpp/grids/gulf_2km_aeqd.nc \
--plot
If --grid-file exists it is loaded and grid-creation flags are ignored;
otherwise the newly built grid is saved there for reuse. Regridding accepts
multiple inputs or quoted wildcard patterns (use --output-dir/--plot-dir
for batches, --output/--plot-output only for single files). Regrid methods:
nearest, gaussian, linear, bilinear, kriging. A --day-night
day/night filter and --variable (default sst_celsius) are also available.
Output layout
/spray/snpp/
├── manifests/
│ ├── VIIRS_NPP-STAR-L2P-v2.80_<start>_<end>_manifest.csv
│ └── VIIRS_NPP-STAR-L2P-v2.80_<start>_<end>_manifest.json
├── raw/
│ └── VIIRS_NPP-STAR-L2P-v2.80/YYYY/MM/DD/*.nc
├── processed/
│ └── VIIRS_NPP-STAR-L2P-v2.80/YYYY/MM/DD/*_processed.nc
├── grids/ # saved reusable target grids (regrid)
├── regridded/ # default regrid outputs and PNG previews
└── footprints/
└── snpp_granule_footprints.parquet
Raw files are checked against what is already on disk and skipped unless
--overwrite-downloads is set; processed files are skipped unless
--overwrite-processed 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 |
|---|---|
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.
The regridder re-derives these fields on the fly for raw inputs and applies
the recommended-quality and day/night masks before resampling.
Shared code
These modules were refactored to import shared helpers from the repo-root
common package so the SNPP and GEOS 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.swath_regrid— pyresample-based swath→grid regridding (build_latlon_grid,load_target_grid,regrid_dataarray, …)common.footprints— incremental SST granule index (odsl-snpp-footprints)
Each script prepends the repo root to sys.path so it runs both as an
installed console script and directly.
Related links
../common— shared regridding and Earthdata utilities../colocate— matchups against the SNPP footprint parquet../README.md— repository conventions and domain gotchas- PO.DAAC dataset: https://podaac.jpl.nasa.gov/dataset/VIIRS_NPP-STAR-L2P-v2.80
(CMR concept ID
C2147480877-POCLOUD)