From 87442c082e0c8413cfa87cdee27bb3e4d1037d0f Mon Sep 17 00:00:00 2001 From: thodson-usgs Date: Thu, 29 Oct 2026 09:07:18 -0500 Subject: [PATCH] fix(waterdata): accept the latest-continuous method_category queryable USGS added method_category to the latest-continuous collection between the 10/28 and 10/29 nightly live runs, on both v0 and v1, which turned three live monitors red. get_continuous has taken it since #423; get_latest_continuous now takes it as a keyword-only parameter and lists it as a returned column. Regenerate the queryables snapshot, and refresh the latest-continuous fixture so it carries one categorized series and one null. Co-Authored-By: Claude Opus 5.5 --- NEWS.md | 2 ++ dataretrieval/waterdata/time_series.py | 10 +++++++++- tests/data/waterdata_ogc_fixtures.json | 18 ++++++++++-------- tests/data/waterdata_queryables.json | 1 + tests/waterdata_test.py | 3 +++ 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/NEWS.md b/NEWS.md index 28dd18fd..11ce324a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,5 @@ +**10/29/2026:** `waterdata.get_latest_continuous()` accepts `method_category`, a column USGS added to the `latest-continuous` collection in October 2026; `get_continuous()` has accepted it since 09/22/2026. It is the RLMS method category code (`STNRD`, `LMTUS`, `EXPER` or `UNKWN`) for the method in effect over an observation's interval, returned on every record and null for time series that have not been categorized. It could already be passed through `**queryables`; it is now a documented, keyword-only parameter. + **10/16/2026:** **Bug fix:** the time-zone table behind the `*DateTime` columns that `waterdata.get_samples()` and `wqp.get_results()` append, and behind `utils.format_datetime()`, now follows the code lists those services use: the USGS NWIS time-zone list (Samples, and the USGS records that the Water Quality Portal passes through) and the WQX TimeZone domain (Water Quality Portal). USGS records write American Samoa as `ZP-11`, which was missing, so every timed American Samoa row from `get_samples()`, and every timed USGS American Samoa row from `get_results()`, had a `NaT` datetime; it is now UTC-11. 39 other codes from the two lists that used to become `NaT` now resolve, among them the remaining `ZP*` offsets, `IDLW`, `IDLE`, `NZT`, `SWT`, and the retired WQX codes `AHST` and `YST`. **Behavior change:** codes that the table read with a different meaning from the USGS list now take the USGS meaning: `CAST` (+9:30), `CCT` (+8), `EASST` (+11), `EAST` (+10), `NFT` (-3:30), `NZDT` (+13), `WAST` (+7), and `WAT` (-1). `FJST` is now UTC+13. Where the two lists disagree, WQX wins: `SST` stays American Samoa (UTC-11), the meaning the Water Quality Portal returns, and `BST` is UTC-11. **10/15/2026:** **Bug fix:** the `ActivityStartDateTime` and `Activity_StartDateTime` columns that `wqp.get_results()` and `waterdata.get_samples()` append, and the `datetime` column of `utils.format_datetime()`, read the time-zone code `GST` as Gulf Standard Time (UTC+4). The USGS time-zone codes and the WQX TimeZone domain both define `GST` as Guam Standard Time (UTC+10), so a sample collected on Guam at 10:00 local time was placed at 06:00 UTC instead of 00:00 UTC. `GST` is now UTC+10, and `HDT` (Hawaii-Aleutian Daylight Time, UTC-9), a USGS code that was missing from the table, now resolves instead of becoming `NaT`. diff --git a/dataretrieval/waterdata/time_series.py b/dataretrieval/waterdata/time_series.py index 093fd1e2..e2ba0c6a 100644 --- a/dataretrieval/waterdata/time_series.py +++ b/dataretrieval/waterdata/time_series.py @@ -496,6 +496,8 @@ def get_latest_continuous( filter_lang: FILTER_LANG | None = None, convert_type: bool = True, max_rows: int | None = None, + *, + method_category: str | Iterable[str] | None = None, **queryables: Any, ) -> tuple[pd.DataFrame, BaseMetadata]: """Get only the most recent observation of each continuous time series. @@ -533,7 +535,7 @@ def get_latest_continuous( The columns to return from the query. Available options are: geometry, id, time_series_id, monitoring_location_id, parameter_code, statistic_id, time, value, unit_of_measure, - approval_status, qualifier, last_modified + approval_status, qualifier, method_category, last_modified time_series_id : string or iterable of strings, optional A unique identifier representing a single time series, corresponding to the id field in the time-series-metadata endpoint. @@ -564,6 +566,12 @@ def get_latest_continuous( sensor may have been impacted by ice or whether values were estimated. Matches observations whose qualifiers are exactly these, in this order: ``"ICE"`` matches ``["ICE"]`` but not ``["ESTIMATED", "ICE"]``. + method_category : string or iterable of strings, optional + The RLMS method category code for the method in effect over the + observation's interval: "STNRD" (standardized, with known uncertainty + and full QA/QC), "LMTUS" (limited use: a modified or externally + sourced method), "EXPER" (experimental), or "UNKWN" (unknown). + Null for time series that have not been categorized. value : string or iterable of strings, optional The value of the observation. Values are transmitted as strings in the JSON response format to preserve precision. diff --git a/tests/data/waterdata_ogc_fixtures.json b/tests/data/waterdata_ogc_fixtures.json index d631cbff..572b1783 100644 --- a/tests/data/waterdata_ogc_fixtures.json +++ b/tests/data/waterdata_ogc_fixtures.json @@ -499,18 +499,19 @@ ], "type": "Point" }, - "id": "2ccf9208-befe-4486-9ce2-0c0e4cff7127", + "id": "333a18ac-e09b-422a-a38c-454f70454475", "properties": { "approval_status": "Provisional", - "last_modified": "2026-08-07T18:55:07.672769+00:00", + "last_modified": "2026-10-29T13:54:19.532512+00:00", + "method_category": "UNKWN", "monitoring_location_id": "USGS-06904500", "parameter_code": "00065", "qualifier": null, "statistic_id": "00011", - "time": "2026-08-07T18:45:00+00:00", + "time": "2026-10-29T13:45:00+00:00", "time_series_id": "b36569a0067443ac9425e850a3ac7baa", "unit_of_measure": "ft", - "value": "1.59" + "value": "0.13" }, "type": "Feature" }, @@ -522,18 +523,19 @@ ], "type": "Point" }, - "id": "862137bb-d9e8-4e99-85a7-be2d82f5daa7", + "id": "26e6625d-342a-4a98-8225-98d84524eefa", "properties": { "approval_status": "Provisional", - "last_modified": "2026-08-07T18:55:14.240081+00:00", + "last_modified": "2026-10-29T13:54:13.767087+00:00", + "method_category": null, "monitoring_location_id": "USGS-06904500", "parameter_code": "00060", "qualifier": null, "statistic_id": "00011", - "time": "2026-08-07T18:45:00+00:00", + "time": "2026-10-29T13:45:00+00:00", "time_series_id": "627c17455f9e4a4286e1d75dde4d8470", "unit_of_measure": "ft^3/s", - "value": "535" + "value": "75.4" }, "type": "Feature" } diff --git a/tests/data/waterdata_queryables.json b/tests/data/waterdata_queryables.json index a47c5320..d904e9cf 100644 --- a/tests/data/waterdata_queryables.json +++ b/tests/data/waterdata_queryables.json @@ -306,6 +306,7 @@ "hydrologic_unit_code", "id", "last_modified", + "method_category", "minor_civil_division_code", "monitoring_location_id", "monitoring_location_name", diff --git a/tests/waterdata_test.py b/tests/waterdata_test.py index fa093024..37078633 100644 --- a/tests/waterdata_test.py +++ b/tests/waterdata_test.py @@ -1172,6 +1172,9 @@ def test_get_latest_continuous(httpx_mock): assert df.columns[-1] == "latest_continuous_id" assert df["time"].dtype.name.startswith("datetime64[") assert "UTC" in df["time"].dtype.name + # One fixture series is categorized and one is not. + assert df["method_category"].iloc[0] == "UNKWN" + assert pd.isna(df["method_category"].iloc[1]) assert hasattr(md, "url") # Multi-value params go in one CQL2 POST when the request fits. sent = _items_requests(httpx_mock, "latest-continuous")