Skip to content

Commit 20f95e7

Browse files
thodson-usgsclaude
andcommitted
feat(waterdata.xarray): record vertical_datum to distinguish stage parameters
Gage height (00065) and stream water level (63160) share the CF standard_name water_surface_height_above_reference_datum, which left them indistinguishable. Attach a vertical_datum attribute (matching USGS's column name) recording the reference datum: "local site datum" for gage height (00065), "NAVD88" for stream water level (63160). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 055fda6 commit 20f95e7

3 files changed

Lines changed: 37 additions & 1 deletion

File tree

dataretrieval/waterdata/types.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,13 @@
123123
"63160": "water_surface_height_above_reference_datum",
124124
"00045": "lwe_thickness_of_precipitation_amount",
125125
}
126+
127+
# USGS parameter code -> vertical reference datum, attached as a
128+
# ``vertical_datum`` attribute. The two water-surface-height parameters share
129+
# the CF standard_name water_surface_height_above_reference_datum, so the datum
130+
# distinguishes them: gage height (00065) is measured from a local site (gage)
131+
# datum, while stream water level (63160) is referenced to NAVD88.
132+
CF_VERTICAL_DATUM = {
133+
"00065": "local site datum",
134+
"63160": "NAVD88",
135+
}

dataretrieval/waterdata/xarray.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@
5959

6060
from . import api as _api
6161
from .nearest import get_nearest_continuous as _get_nearest_continuous
62-
from .types import CF_CELL_METHODS, CF_STANDARD_NAMES, CF_UNIT_MAP
62+
from .types import (
63+
CF_CELL_METHODS,
64+
CF_STANDARD_NAMES,
65+
CF_UNIT_MAP,
66+
CF_VERTICAL_DATUM,
67+
)
6368

6469
__all__ = [
6570
"get_continuous",
@@ -250,6 +255,9 @@ def _var_attrs(desc, *, unit, pcode, stat, default_cell_method, ancillary, name)
250255
sn = CF_STANDARD_NAMES.get(str(pcode))
251256
if sn:
252257
attrs["standard_name"] = sn
258+
datum = CF_VERTICAL_DATUM.get(str(pcode))
259+
if datum:
260+
attrs["vertical_datum"] = datum
253261
attrs["usgs_parameter_code"] = str(pcode)
254262

255263
if stat is not None and _pd.notna(stat):

tests/waterdata_xarray_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,24 @@ def test_missing_standard_name_is_omitted():
100100
assert ds["mystery"].attrs["usgs_parameter_code"] == "99999"
101101

102102

103+
def test_vertical_datum_distinguishes_stage_parameters():
104+
# 00065 (gage height) and 63160 (water level above NAVD88) share the CF
105+
# standard_name water_surface_height_above_reference_datum; the vertical_datum
106+
# attribute records the differing reference datum so they're distinguishable.
107+
for pcode, datum in (("00065", "local site datum"), ("63160", "NAVD88")):
108+
df = _daily_frame()
109+
df["parameter_code"] = pcode
110+
ds = wdx._build_ragged(df, _meta(), service="continuous", series_meta={})
111+
v = ds["value"]
112+
assert v.attrs["standard_name"] == "water_surface_height_above_reference_datum"
113+
assert v.attrs["vertical_datum"] == datum
114+
# a parameter with no datum mapping gets no vertical_datum attr
115+
ds = wdx._build_ragged(
116+
_daily_frame(), _meta(), service="daily", series_meta=_DISCHARGE_META
117+
)
118+
assert "vertical_datum" not in ds["value"].attrs
119+
120+
103121
def test_multiple_parameters_outer_join_on_time():
104122
# discharge at t1,t2 ; temperature at t2,t3 -> union time, NaN fill
105123
q = _daily_frame(values=(100, 110), times=("2024-06-01", "2024-06-02"))

0 commit comments

Comments
 (0)