Overview¶
haxr is the companion library for the HAXR dataset.
It provides:
an easy, local-cache-based access layer for the dataset files (radar + AIS + station metadata), and
a handful of pragmatic utilities for working with the radar stream (cycles/frames) and for building quick visualizations (histogram helpers).
The dataset is distributed as a set of per-station, per-hour Chunk. Each chunk
contains one radar HDF5 file and one AIS CSV file.
Installation¶
Install the latest stable release from PyPI:
pip install haxr
If you want to work with/on the most recent version, find further instructions in the README.md of our GitHub repository.
Contributions are welcome! Please feel free to open an issue or pull request.
Quickstart¶
The main entry point is Store. It manages a local cache directory
and (optionally) downloads missing files from a dataset release endpoint.
from haxr import DOI, Store
from haxr.utilities import load_cycle, iter_frames
# Pick a release endpoint. For reproducible workflows prefer a versioned DOI.
base_url = DOI.latest
print("DOI:", base_url.removesuffix("/files"))
with Store(base_url=base_url) as store:
# Discover what’s available
chunks = store.list_chunks(station="altona")
# Select one chunk (station + UTC hour split)
chunk = store.get_chunk(station="altona", split_hour_utc=9)
# Open the radar HDF5 file (download into cache if needed)
with store.open(chunk.radar_file) as radar:
df0 = load_cycle(radar, k=0)
# Iterate a sparse subset of cycles ("frames")
for k in iter_frames(radar, k=0, n=5):
df = load_cycle(radar, k=k)
...
# Load AIS data as a DataFrame
ais = store.load_ais_data(chunk.ais_file)
Cycle vs Frame¶
The radar data is a time-ordered stream of reflection measurements (“cells”), each associated with an azimuth angle (antenna bearing) and a range (distance). The antenna rotates clockwise; one full rotation takes a few seconds.
In the HDF5 radar files, the raw measurements are stored as a single, growing sequence of cells.
The group cycle provides two 1D datasets, cycle/first and cycle/last, that define inclusive index ranges into this cell stream.
A cycle is intended to represent one full antenna rotation, but there is no canonical choice for where a rotation starts (and thus ends).
Instead, the dataset defines cycles as a sliding window: for (almost) every azimuth step, it gives you the window of cells you need to accumulate to cover approximately one full turn.
As a consequence, consecutive cycles overlap heavily: two adjacent entries in cycle/first typically differ by roughly one azimuth step, so almost all cells are shared between adjacent cycles (except for the small part that enters/leaves the sliding window).
For many tasks (annotation, one image per rotation, downsampling in time) this dense, overlapping representation is inconvenient.
Therefore, haxr introduces the notion of a frame:
A frame is still “one full rotation”, but chosen such that adjacent frames do not overlap in the cell stream.
Given a cycle index
k, the next frame is defined as the first cycle indexk_nextwithcycle/first[k_next] > cycle/last[k](strictly forward in time).
In other words: cycles and frames both cover about one full rotation, but cycles advance by ~one azimuth step (almost complete overlap), whereas frames advance by ~one full rotation (no overlap).
Utilities provided for this:
iter_frames()yields the cycle indices of successive frames.load_frames()loads several frames and adds aframecolumn.
API at a glance¶
Dataset release endpoints¶
DOIis anenum.StrEnumof known dataset release endpoints (usable asStore(base_url=...)).
Cache + access layer¶
Storemanages the local cache and provides:load_ais_data()(loads CSV data in apandas.DataFrame)stations(station metadata table)
Radar stream utilities¶
load_cycle()loads one cycle into apandas.DataFrame(including derived mid-point columns for azimuth/range).iter_frames(),load_frames()help you work with non-overlapping “frames”.
Visualization helpers¶
fill_histogram()builds a 2D histogram in polar coordinates (azimuth, range), with optional weights (e.g., amplitude values).histogram_to_cartesian_meshgrid()converts that polar histogram to Cartesian meshgrids suitable for plotting (e.g., withmatplotlib.axes.Axes.pcolormesh()).
Notes on reproducibility¶
Store is a convenience wrapper around cached files on disk; it is
not a dataset version manager. If you care about reproducibility, pin the release
endpoint (e.g. a versioned DOI member) and avoid mixing different
releases in the same cache directory.