Quickstart¶
Fast NEXRAD Level 2 processing for Python. This page goes from a fresh
environment to a working open_datatree call against a public S3 file.
Install¶
Python 3.11+ is required. See Install for source builds and platform notes.
Open a volume as an xradar DataTree¶
radrs.xradar.open_datatree is a drop-in replacement for
xradar.io.open_nexradlevel2_datatree. It returns an xarray.DataTree with
the same sweep-per-node structure.
import radrs.xradar as rxr
src = "s3://unidata-nexrad-level2/2024/03/15/KTLX/KTLX20240315_000217_V06"
dt = rxr.open_datatree(src)
The src argument also accepts a local filesystem path or a bytes buffer
of raw NEXRAD data.
Open the same volume as a raystack DataTree¶
The raystack format is a flat vcps / sweeps / returns / activity
layout designed for ML training pipelines that want fixed-shape tensors
rather than nested xradar groups.
import radrs.raystack as rrs
rdt = rrs.open_datatree(src, fold_size=128)
rdt["returns"]["DBZH"].shape # (n_returns, 128)
fold_size chunks each radial along the range axis: a radial with
n_gates > fold_size becomes ceil(n_gates / fold_size) returns of
fold_size gates each, NaN-padded past the last real gate. The range
coordinate is the gate's index within its fold, not a distance. See
Raystack format for the array layout
and for recovering physical range, and
Batch iteration and folding for how fold_size trades
rows against columns.
XArray integration¶
Both readers are also registered as xarray engines, so they can be reached
through xarray.open_datatree / open_dataset dispatch instead of the radrs
APIs directly:
import xarray as xr
dt = xr.open_datatree(src, engine="radrs-xradar", sort_by_azimuth=True)
sweep = xr.open_dataset(src, engine="radrs-xradar", group="sweep_0")
rs_dt = xr.open_datatree(src, engine="radrs-raystack", fold_size=128)
returns = xr.open_dataset(src, engine="radrs-raystack", group="returns")
Each engine forwards its reader's keywords (sort_by_azimuth for
radrs-xradar; fold_size, qc, include_activity for radrs-raystack),
plus group, drop_variables, and storage_options. Decoder keywords such as
mask_and_scale are rejected — the engines return already-decoded in-memory
objects. radrs.xradar and radrs.raystack remain the canonical APIs; the
engines are thin adapters for pipelines built around xarray dispatch.
Anonymous S3 access¶
The single-volume open_datatree path fetches from S3 without signing, so
public buckets like unidata-nexrad-level2 and noaa-nexrad-level2 work
out of the box even without AWS credentials.
For multi-volume iteration over an archive, pass
storage_options={"anon": "true"} to NexradL2ArchiveIter:
from datetime import datetime, timezone
import radrs
archive = radrs.NexradL2ArchiveIter(
base_uri="s3://unidata-nexrad-level2",
start_time=datetime(2024, 3, 15, tzinfo=timezone.utc),
end_time=datetime(2024, 3, 16, tzinfo=timezone.utc),
storage_options={"anon": "true"},
site_filter=["KTLX"],
)
Archive bounds are UTC and half-open, [start_time, end_time): naive
datetimes are read as UTC rather than as local time, and a volume exactly at
end_time is excluded. See
Iterating an archive for the full surface.
Accumulate a time range into one array¶
BatchedRaystack fills pre-allocated buffers from an archive iterator, so a
whole time range becomes a single returns matrix:
import radrs.raystack as rrs
batch = rrs.BatchedRaystack(
max_vcps=20, max_sweeps=20 * 32, max_returns=20 * 90_000,
fold_size=256, drop_empty_returns=True,
)
n_added = batch.add_volumes_from_l2(archive, prefetch=8)
rs_dt = batch.finalize_to_rs_dt()
Capacity is reserved up front, so max_returns has to be estimated before the
first fetch and n_added has to be checked afterwards. See
Batch iteration and folding for the sizing arithmetic.
What's next¶
- Raystack format — what
vcps,sweeps,returns, andactivityactually contain, with a visual folding walkthrough. - Batch iteration and folding —
NexradL2ArchiveIter,BatchedRaystackcapacity sizing,prefetch,drop_empty_returns, and fixed-shape output. - Quality control —
RhohvThreshold,SunSpike, andVradhWindingNumberapplied during raystack parsing. - xradar interop — sweep ordering, NaN semantics for
below-threshold gates, and the
sort_by_azimuthflag. - Visualization — the marimo viewers for a single volume and for a whole batch.