Overview
rads handles conventional nadir altimetry distributed through the
Radar Altimeter Database System (RADS). RADS
stores each mission as thousands of small pass-level NetCDF files, one per
half-orbit. This package repackages those pass files into cycle NetCDFs and
subsets a bounding box into one along-track NetCDF4 of detided SSHA.
/spray/rads/data/{mission}/{phase}/c{cycle}/{mission}p{pass}c{cycle}.nc
Scanning that many files is the bottleneck for downstream mapping and optimal
interpolation. Cycle repack writes one regular NetCDF per mission / phase /
cycle, with (pass, sample) dimensions and missing passes / unused sample slots
filled. Regional subset writes one concatenated (obs,) table. Both reuse the
same search, indexing, and time/bbox helpers, plus a demo SSHA map.
Missions are addressed by their RADS directory codes (j2 j3 3a 3b 6a,
…) and phases by their letter subdirectories (a b c, …).
Installation & dependencies
Install the odsl distribution in editable mode from the repo root:
python -m pip install -e . # core repackaging + subsetting
python -m pip install -e ".[plot]" # adds cartopy for the demo map
- Core deps (always installed):
numpy,pandas,netCDF4. The repackaging and indexing paths need nothing more. plotextra (cartopy): onlydemo_plot_gulf_america_ssha.pyneeds it. The demo degrades gracefully to a plain matplotlib axes if cartopy is absent.
Entry points & scripts
| File | Console script | Purpose |
|---|---|---|
repack_rads_cycles.py |
odsl-rads-repack |
Repackage pass files into one NetCDF per mission/phase/cycle. |
subset_region.py |
odsl-rads-subset |
Subset all missions in a bbox to one along-track NetCDF4 (ssha − tide_internal). |
utils.py |
— (library) | RADS root/table constants, BBox, pass discovery/indexing, time & bbox filtering, subset_rads_*. |
demo_plot_gulf_america_ssha.py |
— (run directly) | Search + subset SSHA for a bbox/time window and save a PNG map. |
Reusable logic lives in utils.py; the scripts stay thin (see
../README.md#conventions).
Usage
Repackage a range of Jason-3 cycles, phase c, using the curated core
variables and rebuilding the pass index:
odsl-rads-repack \
--missions j3 \
--phases c \
--cycles 500 501 510-520 \
--out-dir /spray/rads/cycle_files \
--refresh-index
Repackage several missions at once (defaults: --shape-mode mission,
--variable-mode core, --index-source auto, --compression-level 4):
odsl-rads-repack --missions j2 j3 3a 3b 6a --out-dir /spray/rads/cycle_files
Write every 1-D time variable, keep float64, and unpack scaled variables to physical floats:
odsl-rads-repack --missions j3 --cycles 500 \
--variable-mode all --keep-float64 --unpack-scaled
Smoke-test on the first two cycle groups only, using tables-only indexing:
odsl-rads-repack --missions j3 --index-source tables --limit-cycles 2
Subset every nadir mission over the Gulf of America into one NetCDF4. Output
ssha is the RADS precomputed SLA (standard corrections already applied) minus
tide_internal (HRET v8.1). --discover-passes learns intersecting pass
numbers from the first hit cycle per mission/phase so a full-archive run does
not open every global file:
odsl-rads-subset \
--bbox -98 18 -80 31 \
--out tmp/rads_gulf_america_ssha.nc \
--discover-passes
Optional --start / --end / --missions / --passes restrict the extract.
Ocean-only is the default (topo < 0); keep land with --allow-land.
Samples (and whole older missions such as ERS / Geosat / Envisat / CryoSat-2
in this archive) without tide_internal are dropped so the file never mixes
tided and detided SSHA.
Plot RADS SSHA over the Gulf of America for a date range (needs [plot]):
python rads/demo_plot_gulf_america_ssha.py \
--start 2025-01-01 --end 2025-01-10 \
--bbox -98 18 -80 31 \
--out tmp/rads_gulf_america_ssha_20250101_20250110.png
Key odsl-rads-repack flags (see build_parser() for the full set):
--root/--tables-dir/--out-dir— RADS input root,.pastables dir, output root.--missions/--phases/--cycles— filters; cycles accept ints andA-Branges.--index-file/--refresh-index— index CSV path (defaultOUT_DIR/lookup_tables/rads_pass_index.csv) and rebuild toggle.--index-source {auto,tables,netcdf}— build the index from.pastables, NetCDF headers, or tables with NetCDF fallback (auto).--shape-mode {mission,cycle}— fixed mission/phase dims for every cycle, or minimal per-cycle dims.--variable-mode {core,all}/--variables …— curated core set, all 1-D time vars, or an explicit list.--keep-float64/--unpack-scaled— keep float64 instead of float32; unpackscale_factor/add_offsetvariables.--compression-level 0-9/--overwrite/--limit-cycles N.
Data layout / outputs
Output files are written under:
OUT_DIR/{mission}/{phase}/{mission}_{cycle:03d}_{start}_{end}.nc
Each cycle NetCDF (NETCDF4) has dimensions pass and sample, plus:
- Coordinate / bookkeeping vars on
(pass,):pass(RADS pass number),n_valid(valid samples per pass),pass_present(0/1 flag),source_file. - Data vars on
(pass, sample): the selected core orallvariables (time,lat,lon,ssha,flags, tide/tropo/MSS/MDT fields, …).timeis always float64. - Global attrs:
title,source,mission,phase,cycle_number,mission_name,time_coverage_start/end,history.
A run summary is written to OUT_DIR/repack_summary.csv, and the pass metadata
index to OUT_DIR/lookup_tables/rads_pass_index.csv (reused on later runs
unless --refresh-index).
Colocate reads rads.utils.DEFAULT_PASS_INDEX
(/spray/rads/data/lookup_tables/rads_pass_index.csv) instead of scanning
data/{sat}/{cycle}/. Refresh that table with
odsl-colocate-refresh refresh --targets rads (or --refresh-index on a
repack whose --out-dir is /spray/rads/data). The CSV carries pass times;
bbox is applied when the NetCDF is opened.
The default core variable set:
time lat lon ssha flags surface_type dist_coast topo_srtm15plus topo_ace2
seaice_conc seaice_conc_era5 swh_ku sig0_ku wind_speed_alt
dry_tropo_era5 wet_tropo_era5 inv_bar_static_era5 tide_ocean_fes14
tide_load_fes14 tide_solid tide_pole mss_dtu21 mss_cnescls15 mdt_cnescls18
Conventions & notes
- Packed variables preserved. Integer variables carrying
scale_factor/add_offsetkeep their packed dtype, fill value, and scale metadata by default (readers decode on the fly).--unpack-scaledwrites physical floats instead. Floats downcast to float32 unless--keep-float64. --shape-mode missionwith--cycles. The mission/phase pass axis and sample length are computed from the full selected mission/phase index, then only the requested cycles are written — so cycle files stay dimensionally aligned across a mission.--limit-cyclessemantics. A debugging guard that keeps only the firstNcycle groups (groups[:N]). It is checked withis not None, so an explicit--limit-cycles 0correctly writes nothing rather than being treated as "unlimited".BBoxdateline handling.utils.BBox(used by the demo and subset helpers) normalizes longitudes to[0,360)and tests membership by angular offset from the western edge, so boxes that cross the antimeridian (e.g.west=170, east=-170) work correctly. A full-globe span is detected when west == east..pastables.--index-source auto/tablesreads cycle, pass, start/end time, and sample count from lightweight/spray/rads/tables/*.pasfiles, avoiding opening every NetCDF. Mission/phase pairs without a clean table match fall back to NetCDF header reads.- Shared plotting.
demo_plot_gulf_america_ssha.pydraws basemap context viacommon.plotting.add_map_context(ax, bbox)rather than a local helper.
Related
../common— shared plotting (add_map_context) and swath→grid regridding.../colocate— matchups againstDEFAULT_PASS_INDEX.../multi_altimeters— multi-altimeter optimal interpolation that consumes these repackaged RADS cycle files (alongside SWOT).../README.md— repo-wide conventions (CLI structure, bbox handling,/spraydata roots, packed-variable preservation).