API reference¶
Auto-generated from the AquaScope source. Every public function, class, and method appears below, with its docstring rendered in NumPy style.
If you're looking for a guided introduction, start with Getting started or Features. This page is the exhaustive reference.
High-level API¶
The most common entry points live in aquascope.api:
aquascope.api ¶
High-level convenience API for common hydrological analyses.
Provides one-liner functions wrapping AquaScope's lower-level modules. Designed for quick analyses in Jupyter notebooks and scripts.
Examples:
>>> from aquascope.api import flood_analysis, baseflow_analysis
>>> result = flood_analysis(daily_discharge, method="gev", return_periods=[10, 50, 100])
>>> bf = baseflow_analysis(daily_discharge, method="eckhardt")
flood_analysis ¶
flood_analysis(discharge: Series, method: str = 'gev', return_periods: list[int] | None = None, ci_level: float = 0.9, regional_skew: float | None = None, **kwargs) -> FloodFreqResult
Fit a flood-frequency distribution and estimate return-period quantiles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Daily (or sub-daily) discharge time-series with a
:class: |
required |
method
|
str
|
Distribution to fit. One of |
'gev'
|
return_periods
|
list[int] | None
|
List of return periods (years) for which to estimate quantiles.
Defaults to |
None
|
ci_level
|
float
|
Confidence level for bootstrap confidence intervals (GEV only). |
0.9
|
regional_skew
|
float | None
|
Optional regional skew coefficient (LP3 only). |
None
|
**kwargs
|
Forwarded to the underlying fitting function. |
{}
|
Returns:
| Type | Description |
|---|---|
FloodFreqResult
|
Fitted distribution parameters, quantile estimates, and confidence intervals. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If method is not one of the supported methods. |
Source code in aquascope/api.py
baseflow_analysis ¶
Separate baseflow from quickflow using a digital filter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Daily discharge time-series. |
required |
method
|
str
|
|
'lyne_hollick'
|
**kwargs
|
Forwarded to the filter function (e.g. |
{}
|
Returns:
| Type | Description |
|---|---|
BaseflowResult
|
DataFrame of total / baseflow / quickflow plus BFI. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If method is not supported. |
Source code in aquascope/api.py
flow_duration ¶
Compute a flow-duration curve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Daily discharge time-series. |
required |
**kwargs
|
Forwarded to :func: |
{}
|
Returns:
| Type | Description |
|---|---|
FDCResult
|
Exceedance probabilities, sorted discharges, and percentile values. |
Source code in aquascope/api.py
compute_all_signatures ¶
Compute a comprehensive set of hydrological signatures.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Daily discharge time-series. |
required |
**kwargs
|
Forwarded to :func: |
{}
|
Returns:
| Type | Description |
|---|---|
SignatureReport
|
Dataclass containing ~20 hydrological signature values. |
Source code in aquascope/api.py
detect_changepoints ¶
Detect abrupt shifts in a time-series.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
series
|
ndarray | Series
|
One-dimensional numeric data. |
required |
method
|
str
|
Detection algorithm. One of |
'pelt'
|
**kwargs
|
Forwarded to the detection function. |
{}
|
Returns:
| Type | Description |
|---|---|
ChangePointResult
|
Detected change-points, segment summaries, and test statistics. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If method is not supported. |
Source code in aquascope/api.py
fit_copula ¶
fit_copula(x: ndarray | Series, y: ndarray | Series, family: str = 'auto', **kwargs) -> CopulaResult
Fit a bivariate copula to paired observations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
ndarray | Series
|
Paired data arrays of equal length. |
required |
y
|
ndarray | Series
|
Paired data arrays of equal length. |
required |
family
|
str
|
Copula family — |
'auto'
|
**kwargs
|
Forwarded to :func: |
{}
|
Returns:
| Type | Description |
|---|---|
CopulaResult
|
Fitted copula parameters, dependence measures, and AIC. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If family is not supported. |
Source code in aquascope/api.py
trend_analysis ¶
trend_analysis(series: ndarray | Series | list[float], alpha: float = 0.05, method: str = 'original') -> MannKendallResult
Perform a Mann-Kendall trend test with Sen's slope estimation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
series
|
ndarray | Series | list[float]
|
Time-series data. |
required |
alpha
|
float
|
Significance level (default: |
0.05
|
method
|
str
|
Mann-Kendall test variant ( |
'original'
|
Returns:
| Type | Description |
|---|---|
MannKendallResult
|
Test statistics, p-value, trend classification, and Sen's slope. |
Source code in aquascope/api.py
mann_kendall ¶
mann_kendall(series: ndarray | Series | list[float], alpha: float = 0.05, method: str = 'original') -> MannKendallResult
Alias for :func:trend_analysis.
Source code in aquascope/api.py
sens_slope ¶
Estimate Sen's slope for a time series.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
series
|
ndarray | Series | list[float]
|
Time-series data. |
required |
Returns:
| Type | Description |
|---|---|
SensSlopeResult
|
Slope, intercept, and sample counts. |
Source code in aquascope/api.py
bayesian_regression ¶
bayesian_regression(X: ndarray | DataFrame, y: ndarray | Series, degree: int = 1, **kwargs) -> PosteriorResult
Fit a Bayesian linear or polynomial regression.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
ndarray | DataFrame
|
Feature matrix (degree=1) or 1-D predictor (degree>1). |
required |
y
|
ndarray | Series
|
Response variable. |
required |
degree
|
int
|
Polynomial degree. |
1
|
**kwargs
|
Forwarded to the model constructor (e.g. |
{}
|
Returns:
| Type | Description |
|---|---|
PosteriorResult
|
Posterior summaries, credible intervals, and diagnostics. |
Source code in aquascope/api.py
ensemble_forecast ¶
ensemble_forecast(models: list[tuple[str, object]], X_train: DataFrame, y_train: Series, X_test: DataFrame, method: str = 'stacking', **kwargs) -> np.ndarray
Train an ensemble of models and return predictions on X_test.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
models
|
list[tuple[str, object]]
|
List of |
required |
X_train
|
DataFrame
|
Training features. |
required |
y_train
|
Series
|
Training target. |
required |
X_test
|
DataFrame
|
Test features. |
required |
method
|
str
|
Ensemble strategy — |
'stacking'
|
**kwargs
|
Forwarded to the ensemble constructor. |
{}
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Predicted values for X_test. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If method is not supported. |
Source code in aquascope/api.py
generate_report ¶
Create a pre-configured :class:~aquascope.reporting.builder.ReportBuilder.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Report title. |
required |
**kwargs
|
Forwarded to :class: |
{}
|
Returns:
| Type | Description |
|---|---|
ReportBuilder
|
A builder instance ready for method-chaining. |
Source code in aquascope/api.py
groundwater_analysis ¶
Run a groundwater analysis on a water-level time series.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
levels
|
Series
|
Water-level measurements with :class: |
required |
method
|
str
|
Analysis type — |
'trend'
|
**kwargs
|
Forwarded to the underlying function. |
{}
|
Returns:
| Type | Description |
|---|---|
dict
|
Result dataclass from the chosen analysis, accessed as a dict or the original dataclass depending on method. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If method is not supported. |
Source code in aquascope/api.py
climate_downscale ¶
climate_downscale(obs: Series, gcm_hist: Series, gcm_future: Series, method: str = 'quantile_mapping', **kwargs) -> pd.Series
Downscale a GCM projection using statistical bias correction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obs
|
Series
|
Observed station data. |
required |
gcm_hist
|
Series
|
GCM historical simulation (overlapping period with obs). |
required |
gcm_future
|
Series
|
GCM future projection to downscale. |
required |
method
|
str
|
Downscaling method — |
'quantile_mapping'
|
**kwargs
|
Forwarded to the underlying function. |
{}
|
Returns:
| Type | Description |
|---|---|
Series
|
Bias-corrected future projection. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If method is not supported. |
Source code in aquascope/api.py
climate_indices ¶
climate_indices(precip: Series | None = None, temperature: Series | None = None, pet: Series | None = None, index: str = 'cdd', **kwargs) -> object
Compute a climate index from meteorological data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
precip
|
Series | None
|
Precipitation series (required for |
None
|
temperature
|
Series | None
|
Maximum temperature series (required for |
None
|
pet
|
Series | None
|
Potential evapotranspiration (required for |
None
|
index
|
str
|
Index to compute — |
'cdd'
|
**kwargs
|
Forwarded to the underlying function. |
{}
|
Returns:
| Type | Description |
|---|---|
object
|
Result dataclass or value from the chosen index. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If index is not supported or required input is missing. |
Source code in aquascope/api.py
budyko_analysis ¶
budyko_analysis(precipitation: float | ndarray, pet: float | ndarray, curves: list[str] | None = None, fu_omega: float = 2.0, observed_et: float | ndarray | None = None, observed_runoff: float | ndarray | None = None) -> BudykoResult
Partition long-term precipitation under the Budyko framework.
The long-term water balance P = ET + Q (storage change neglected)
means a catchment is placed from either of its observed fluxes:
actual evapotranspiration (observed_et) or runoff (observed_runoff,
converted via ET = P - Q). Exactly one may be given.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
precipitation
|
float | ndarray
|
Long-term mean annual precipitation (mm/yr), scalar or array. |
required |
pet
|
float | ndarray
|
Long-term mean annual potential evapotranspiration (mm/yr). |
required |
curves
|
list[str] | None
|
Budyko curves to evaluate. Any subset of |
None
|
fu_omega
|
float
|
Fu/Zhang shape parameter |
2.0
|
observed_et
|
float | ndarray | None
|
Optional observed long-term evapotranspiration (mm/yr), requiring
|
None
|
observed_runoff
|
float | ndarray | None
|
Optional observed long-term runoff (mm/yr), requiring
|
None
|
Returns:
| Type | Description |
|---|---|
BudykoResult
|
Predicted evaporative ratios, the observed position when one observed flux is given, and the curve family over the canonical aridity grid. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If curves is empty or names an unsupported curve, or both observed fluxes are given. |
Source code in aquascope/api.py
Data collectors¶
37 unified collectors. Every collector returns records in the same Pydantic schema.
aquascope.collectors ¶
Data collectors for Taiwan and global water data sources.
AquastatCollector ¶
Bases: BaseCollector
Collect country-level water data from FAO AQUASTAT.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
CachedHTTPClient | None
|
HTTP client instance. A default is created if None. |
None
|
References
FAO. (2023). AQUASTAT. https://www.fao.org/aquastat/
fetch_raw ¶
fetch_raw(country_code: str = 'all', variable_ids: list[int] | None = None, start_year: int = 2000, end_year: int = 2023, **kwargs: Any) -> list[dict]
Fetch raw AQUASTAT data from the FAOSTAT API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
country_code
|
str
|
ISO3 country code, or |
'all'
|
variable_ids
|
list[int] | None
|
AQUASTAT variable IDs. Defaults to all key variables. |
None
|
start_year
|
int
|
Start year (default 2000). |
2000
|
end_year
|
int
|
End year (default 2023). |
2023
|
Returns:
| Type | Description |
|---|---|
list[dict]
|
Raw API response records. |
normalise ¶
Convert raw FAOSTAT response into AquastatRecord objects.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
list[dict]
|
Records from |
required |
Returns:
| Type | Description |
|---|---|
Sequence[AquastatRecord]
|
Normalised AQUASTAT records. |
BaseCollector ¶
Bases: ABC
Every collector must implement fetch_raw and normalise.
The public entry-point is collect() which chains those two steps.
fetch_raw
abstractmethod
¶
Fetch raw data from the upstream API.
Raises: CollectorError: When an endpoint fails hard (e.g. HTTP 4xx/5xx, transport/connection failure, invalid response body). An empty collection should only be returned when the API genuinely answered with zero results.
normalise
abstractmethod
¶
Convert raw API response into unified Pydantic records.
stations ¶
stations(*, bbox: tuple[float, float, float, float] | None = None, variable: str | None = None, max_items: int | None = None) -> list[Station]
Return this source's station catalog.
Sources that expose a catalog override this. bbox is
(west, south, east, north) in WGS84 degrees, variable is one
of :data:aquascope.schemas.station.VARIABLES, and max_items
caps the result for sources whose catalog is large. The default
raises so callers (and the registry drift guard) can tell "no
catalog" from "empty catalog".
supports_stations
classmethod
¶
True when this collector overrides :meth:stations.
collect ¶
Fetch + normalise in one call.
By default returns the list of unified Pydantic records. Set
as_xarray=True to get an xarray.Dataset (time-series) or
as_geodataframe=True to get a geopandas.GeoDataFrame (point
geometry) instead — both require the interop extra. The two flags
are mutually exclusive.
CollectorError ¶
CollectorError(message: str, *, source: str = '', url: str = '', status_code: int | None = None, cause: Exception | None = None)
Bases: RuntimeError
Raised when a data collector encounters a hard endpoint or network failure.
Distinguishes hard failures (HTTP 4xx/5xx, connection timeouts, malformed payloads) from genuine empty results (e.g. a valid query returning zero records). Carries the collector source name, target URL, optional HTTP status code, and the underlying cause exception.
BOMCollector ¶
Bases: BaseCollector
Collect streamflow, water-level, and storage data from BOM Water Data Online (Australia).
Results are normalised to StreamflowReading (discharge),
WaterLevelReading (gauge/storage/groundwater level), or
WaterQualitySample (everything else), all with
source = DataSource.BOM.
stations ¶
stations(*, bbox: tuple[float, float, float, float] | None = None, variable: str | None = None, max_items: int | None = None) -> list[Station]
BOM Water Data Online station catalog (KiWIS getStationList).
BOM's KiWIS instance only reliably returns parametertype_name
from getStationList when the request is filtered by a single
parameter type — an unfiltered request does return real
coordinates for most rows (~89%), but leaves parametertype_name
blank on the large majority (~76%) of them, making it useless for
grouping stations by variable (confirmed live 2026-08-25: 154,895
rows, 11% with a blank latitude, 76% with a blank
parametertype_name). So this issues one request per BOM
parameter type (or just the ones relevant to variable, when
given) and merges the results by station_no, folding each
parameter type into the shared registry vocabulary via
PARAMETER_VARIABLE_MAP — a station reporting discharge and
water level ends up with variables=("discharge", "water_level").
bbox is sent to KiWIS as its native bbox= filter (as
west,south,east,north) on every request and re-checked
client-side with in_bbox in case KiWIS's box is loose. An
unrecognised variable returns [] without calling the API.
Rows whose coordinates fall outside AU_SANITY_BBOX are dropped
(see that constant's docstring) and counted in a single summary
warning, rather than being returned as if they were real stations.
If every parameter-type request fails, raises a RuntimeError so
the harvest and callers report the outage rather than recording an
empty catalog. If a subset of requests fails, logs a summary warning
naming the lost parameter types and returns the partial catalog.
fetch_raw ¶
fetch_raw(station_id: str | None = None, parameter_type: str = 'Water Course Discharge', start_date: str | None = None, end_date: str | None = None, days: int | None = None, ts_name: str = DEFAULT_TS_NAME, **kwargs: Any) -> list[dict]
Fetch raw observations for a BOM station from Water Data Online.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
station_id
|
str
|
AWRC station number (e.g. |
None
|
parameter_type
|
str
|
BOM parameter type name, e.g. |
'Water Course Discharge'
|
start_date
|
str | None
|
Start date |
None
|
end_date
|
str | None
|
End date |
None
|
days
|
int | None
|
Convenience alternative to |
None
|
ts_name
|
str
|
BOM time-series name. Defaults to the quality-checked merged
daily mean ( |
DEFAULT_TS_NAME
|
Returns:
| Type | Description |
|---|---|
list[dict]
|
Raw observation rows, each merged with station/timeseries metadata. Returns an empty list if no matching time series is found or the upstream API is unreachable. |
normalise ¶
Normalise raw BOM rows into StreamflowReading (discharge),
WaterLevelReading (level-type parameters), or
WaterQualitySample (everything else).
BrazilANACollector ¶
BrazilANACollector(identificador: str | None = None, senha: str | None = None, client: CachedHTTPClient | None = None, legacy_client: CachedHTTPClient | None = None)
Bases: BaseCollector
Collect telemetric streamflow, stage and rainfall data from ANA Hidroweb.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
identificador
|
str | None
|
CPF/CNPJ registered with ANA for API access. Falls back to the
|
None
|
senha
|
str | None
|
Password for |
None
|
client
|
CachedHTTPClient
|
Injected for testing; a default client is created otherwise. |
None
|
legacy_client
|
CachedHTTPClient
|
Client for the legacy conventional-network service; a default one is created otherwise. |
None
|
Notes
Credentials are only needed for :meth:fetch_raw's default telemetric
mode. :meth:stations (public SNIRH catalog) and
fetch_raw(mode="historical", ...) (legacy conventional-network
series) both work without them.
stations ¶
stations(*, bbox: tuple[float, float, float, float] | None = None, variable: str | None = None, max_items: int | None = None, telemetric_only: bool = True) -> list[Station]
SNIRH station catalog. telemetric_only restricts to stations with live telemetry
(the ones :meth:fetch_raw can actually query); set it to False to see the full
conventional network too.
fetch_raw ¶
fetch_raw(station_ids: Sequence[str] | str | None = None, start_date: str | date | None = None, end_date: str | date | None = None, days: int = 30, mode: str = 'telemetric', variables: Sequence[str] = ('discharge',), **kwargs) -> list[dict]
Fetch readings for one or more stations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
station_ids
|
str | Sequence[str]
|
One or more ANA station codes (see :meth: |
None
|
start_date
|
str | date
|
Window bounds, |
None
|
end_date
|
str | date
|
Window bounds, |
None
|
days
|
int
|
Size of the default window when |
30
|
mode
|
('telemetric', 'historical')
|
|
"telemetric"
|
variables
|
Sequence[str]
|
Which parameters to request in |
('discharge',)
|
CAMELSBRCollector ¶
Bases: BaseCollector
Collect CAMELS-BR observed daily streamflow records.
fetch_raw ¶
fetch_raw(station_ids: list[str] | None = None, start: str | None = None, end: str | None = None, **kwargs) -> list[dict]
Fetch CAMELS-BR streamflow records, optionally filtered.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
station_ids
|
list[str]
|
Restrict to specific gauge codes (e.g. ["10500000", "11400000"]). |
None
|
start
|
str
|
ISO date strings ("YYYY-MM-DD") bounding the date range. Both are inclusive. If omitted, no date filtering is applied. |
None
|
end
|
str
|
ISO date strings ("YYYY-MM-DD") bounding the date range. Both are inclusive. If omitted, no date filtering is applied. |
None
|
CAMELSCLCollector ¶
Bases: BaseCollector
Collect CAMELS-CL observed daily streamflow (q_m3s_day.csv) records.
fetch_raw ¶
fetch_raw(station_ids: list[str] | None = None, start: str | None = None, end: str | None = None, **kwargs) -> list[dict]
Fetch CAMELS-CL streamflow records, optionally filtered.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
station_ids
|
list[str]
|
Restrict to specific gauge codes (e.g. ["1001001", "12825002"]). Filtering happens before the wide-to-long melt, so this keeps memory bounded — unlike loading all ~500 stations at once. |
None
|
start
|
str
|
ISO date strings ("YYYY-MM-DD") bounding the date range. Both are inclusive. If omitted, no date filtering is applied. |
None
|
end
|
str
|
ISO date strings ("YYYY-MM-DD") bounding the date range. Both are inclusive. If omitted, no date filtering is applied. |
None
|
ColoradoCDSSCollector ¶
Bases: BaseCollector
Collect telemetry streamflow data from Colorado DWR/CDSS.
fetch_raw ¶
Fetch raw data from the Colorado CDSS API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
abbrev
|
str
|
CDSS station abbreviation. Multiple abbreviations may be supplied as a comma-separated string. |
required |
parameter
|
str
|
CDSS telemetry parameter. |
'DISCHRG'
|
**kwargs
|
Any
|
Additional CDSS query parameters, such as date filters. |
{}
|
normalise ¶
Convert CDSS discharge readings from cfs to m³/s.
CopernicusCollector ¶
Bases: BaseCollector
Fetch GloFAS river-discharge data from Copernicus CDS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset
|
str
|
CDS dataset ID. Default is the GloFAS historical dataset. |
None
|
Example
collector = CopernicusCollector() records = collector.collect( ... latitude=48.85, longitude=2.35, ... year="2023", month=["01", "02", "03"], ... )
fetch_raw ¶
fetch_raw(*, latitude: float, longitude: float, year: str | list[str] = '2023', month: str | list[str] = '01', day: str | list[str] | None = None, variable: str = 'river_discharge_in_the_last_24_hours', product_type: str = 'consolidated', system_version: str = 'version_4_0') -> list[dict]
Fetch data via CDS API and return parsed records.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
latitude
|
float
|
Site coordinates. |
required |
longitude
|
float
|
Site coordinates. |
required |
year
|
str | list[str]
|
Temporal selection. |
'2023'
|
month
|
str | list[str]
|
Temporal selection. |
'2023'
|
day
|
str | list[str]
|
Temporal selection. |
'2023'
|
variable
|
str
|
CDS variable name. |
'river_discharge_in_the_last_24_hours'
|
product_type
|
str
|
CDS-specific dataset options. |
'consolidated'
|
system_version
|
str
|
CDS-specific dataset options. |
'consolidated'
|
normalise ¶
Convert parsed GRIB records into WaterQualitySample objects.
EUWFDCollector ¶
Bases: BaseCollector
Collect water quality data from the EEA WISE SoE Waterbase.
Uses the DiscoData SQL API published by the European Environment Agency.
fetch_raw ¶
fetch_raw(country: str | None = None, water_body_type: str = 'river', year: int | None = None, **kwargs) -> list[dict]
Fetch raw water quality records from the EEA DiscoData API.
Parameters:
country: ISO-2 country code (e.g. "DE", "FR").
water_body_type: "river", "lake", or "groundwater".
year: Calendar year to filter on.
Returns: List of raw record dicts from the API response.
normalise ¶
Convert raw EEA records into unified WaterQualitySample objects.
Parameters:
raw: List of dicts from fetch_raw.
Returns:
Sequence of WaterQualitySample instances.
HubeauHydrometrieCollector ¶
Bases: BaseCollector
Collect real-time river level/discharge data from Hub'Eau (France).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_key
|
str
|
Unused — Hub'Eau is open data with no authentication. Kept for interface parity with other collectors. |
''
|
stations ¶
stations(*, bbox: tuple[float, float, float, float] | None = None, variable: str | None = None, max_items: int | None = None) -> list[Station]
Hub'Eau referentiel/stations: every hydrometric station in service.
Hub'Eau's referentiel does not say which grandeur (H or Q) a station
reports, so variables is ("water_level", "discharge") for all;
the observation endpoints answer that per station. bbox goes to
the API and is re-checked client side.
fetch_raw ¶
fetch_raw(code_station: str | None = None, grandeur_hydro: str | None = None, date_debut_obs: str | None = None, date_fin_obs: str | None = None, days: int | None = None, size: int = 1000, max_items: int | None = 5000, elaborated: str | None = None, **kwargs) -> list[dict]
Fetch observations from Hub'Eau: real-time observations_tr (default)
or the long elaborated series obs_elab when elaborated is set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
elaborated
|
str
|
An elaborated grandeur code (see |
None
|
code_station
|
str
|
Hydrometric station code (e.g. "K002000101"). Sent to the
API as |
None
|
grandeur_hydro
|
str
|
"H" (water level) or "Q" (discharge). Omit to fetch both. |
None
|
date_debut_obs
|
str | None
|
ISO 8601 bounds, e.g. "2026-06-01T00:00:00Z". Built from
|
None
|
days
|
int
|
Last N days from now (UTC). Ignored if |
None
|
size
|
int
|
Page size (Hub'Eau's hard max is 20000). |
1000
|
max_items
|
int
|
Hard cap on total records fetched across all pages. |
5000
|
GEMStatCollector ¶
Bases: BaseCollector
Collect water quality data from the GEMStat Zenodo archive.
Downloads the CSV file, parses rows, and normalises into WaterQualitySample records. Supports filtering by country.
fetch_raw ¶
fetch_raw(country: str | None = None, max_records: int = 5000, parameters: list[str] | None = None, start_date: str | None = None, end_date: str | None = None, **kwargs) -> list[dict]
Download the GEMStat Zenodo archive (once), then join station metadata with observation rows and return filtered results.
The ZIP (~200 MB) is cached to data/cache/ on first call;
subsequent calls load from the local file and are fast.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
country
|
str
|
Full or partial country name (e.g. |
None
|
max_records
|
int
|
Hard cap on returned rows across all parameters (default 5 000). |
5000
|
parameters
|
list[str]
|
Parameter CSV names without |
None
|
start_date
|
str
|
ISO date |
None
|
end_date
|
str
|
ISO date |
None
|
parse_gemstat_csv
staticmethod
¶
Parse a GEMStat CSV string into WaterQualitySample records.
Expected columns: GEMS Station Number, Sample Date, Parameter, Analysis Result, Unit, Latitude, Longitude, Country Code, etc.
GRDCCollector ¶
Bases: BaseCollector
Collect GRDC in-situ (Zenodo) and RSEG satellite-extension (DaRUS) discharge records.
fetch_raw ¶
Fetch raw GRDC records.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source_type
|
str
|
|
'in_situ'
|
max_items
|
int | None
|
Maximum number of records to return. |
50000
|
GreeceHydroscopeCollector ¶
Bases: BaseCollector
Collect river stage, discharge and rainfall from Greece's Hydroscope network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
CachedHTTPClient
|
Injected for testing; a default client is created otherwise. |
None
|
fetch_stations ¶
Fetch one instance's raw station list.
fetch_timeseries ¶
Fetch one instance's raw series catalog.
stations ¶
stations(*, bbox: tuple[float, float, float, float] | None = None, variable: str | None = None, max_items: int | None = None) -> list[Station]
Hydroscope station catalog, restricted to stations that hold data.
fetch_raw ¶
fetch_raw(variable: str = 'discharge', station_ids: Iterable[str] | None = None, bbox: tuple[float, float, float, float] | None = None, start: str | date | None = None, end: str | date | None = None, max_stations: int | None = None, **kwargs) -> list[dict[str, Any]]
Fetch observation rows for one variable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variable
|
str
|
One of |
'discharge'
|
station_ids
|
iterable of str
|
Composite station ids (as emitted by :meth: |
None
|
bbox
|
tuple
|
|
None
|
start
|
str or date
|
Inclusive window, pushed to the server as a download path suffix. Both must be given for the server-side filter to apply; a single bound is applied client-side instead. |
None
|
end
|
str or date
|
Inclusive window, pushed to the server as a download path suffix. Both must be given for the server-side filter to apply; a single bound is applied client-side instead. |
None
|
max_stations
|
int
|
Cap on the number of stations fetched. Left uncapped by default, but worth setting: the full daily stage archive is ~50 MB. |
None
|
normalise ¶
Convert rows into the model matching each row's variable.
Discharge becomes :class:StreamflowReading in m3/s, water level
becomes :class:WaterLevelReading in m, and rainfall becomes
:class:ClimateReading. Rows whose declared unit is not convertible
are dropped rather than assumed.
GreeceOpenhiCollector ¶
Bases: BaseCollector
Collect live discharge, stage, rainfall, climate and water quality from Greece's OpenHi.net network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
CachedHTTPClient
|
Injected for testing; a default client is created otherwise. |
None
|
fetch_groups ¶
Fetch one station's time-series groups (each carries a variable).
fetch_series ¶
Fetch the series inside one group.
unit_symbol ¶
Resolve a unit id to its symbol, with the lookup table cached.
stations ¶
stations(*, bbox: tuple[float, float, float, float] | None = None, variable: str | None = None, max_items: int | None = None) -> list[Station]
OpenHi station catalog, with each station's variables resolved.
Resolving variables costs one request per station, since what a
station measures is only visible in its groups. The client's cache
absorbs that on repeat calls.
fetch_raw ¶
fetch_raw(variable: str = 'discharge', station_ids: Iterable[str | int] | None = None, bbox: tuple[float, float, float, float] | None = None, start: str | date | None = None, end: str | date | None = None, max_stations: int | None = None, latest_only: bool = False, **kwargs) -> list[dict[str, Any]]
Fetch observation rows for one variable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variable
|
str
|
An AquaScope variable name present in :data: |
'discharge'
|
station_ids
|
iterable
|
OpenHi station ids. All stations carrying the variable otherwise. |
None
|
bbox
|
tuple
|
|
None
|
start
|
str or date
|
Pushed to the API as |
None
|
end
|
str or date
|
Pushed to the API as |
None
|
max_stations
|
int
|
Cap on stations fetched. |
None
|
latest_only
|
bool
|
Use |
False
|
normalise ¶
Convert rows into the model matching each row's variable.
Discharge becomes :class:StreamflowReading in m3/s and stage
:class:WaterLevelReading in metres, both converted from whatever
unit the API declares; a unit that is not convertible drops the row
rather than being assumed. Rainfall, evaporation and the atmospheric
and soil variables become :class:ClimateReading, and the in-water
chemistry becomes :class:WaterQualitySample.
IndiaWRISCollector ¶
IrelandOPWCollector ¶
Bases: BaseCollector
Collect real-time river/lake water level from Ireland's OPW (waterlevel.ie).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
CachedHTTPClient
|
Injected for testing; a default client is created otherwise. |
None
|
fetch_stations ¶
Fetch the GeoJSON list of active OPW stations.
stations ¶
stations(*, bbox: tuple[float, float, float, float] | None = None, variable: str | None = None, max_items: int | None = None) -> list[Station]
OPW station catalog from the waterlevel.ie GeoJSON feed.
fetch_raw ¶
fetch_raw(stations: list[dict[str, Any]] | None = None, max_stations: int | None = None, **kwargs) -> list[dict[str, Any]]
Fetch raw water-level rows for every valid OPW station.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stations
|
list of dict
|
Pre-fetched GeoJSON features, to avoid a second station-list call (mainly for tests). Fetched automatically if omitted. |
None
|
max_stations
|
int
|
Cap on the number of stations to fetch series for. |
None
|
JapanMLITCollector ¶
Bases: BaseCollector
Collect water data from Japan MLIT Water Information System.
Supports water-level, discharge, water-quality, and rainfall
observations. Results are normalised to WaterQualitySample
records with source = DataSource.JAPAN_MLIT.
fetch_raw ¶
fetch_raw(station_id: str | None = None, prefecture: str | None = None, parameter: str = 'water_level', start_date: str | None = None, end_date: str | None = None, **kwargs: Any) -> list[dict]
Fetch raw observation data from the MLIT Water Information System.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
station_id
|
str | None
|
MLIT station code (e.g. |
None
|
prefecture
|
str | None
|
Prefecture name in English (e.g. |
None
|
parameter
|
str
|
One of |
'water_level'
|
start_date
|
str | None
|
Start date in ISO format ( |
None
|
end_date
|
str | None
|
End date in ISO format ( |
None
|
**kwargs
|
Any
|
Additional keyword arguments forwarded to the HTTP request. |
{}
|
Returns:
| Type | Description |
|---|---|
list[dict]
|
Raw observation records. Returns an empty list when the upstream API is unreachable or no data matches. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If parameter is not one of the supported types. |
normalise ¶
Normalise raw MLIT data into WaterQualitySample records.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
list[dict]
|
Raw records as returned by |
required |
Returns:
| Type | Description |
|---|---|
list[WaterQualitySample]
|
Unified water-quality sample records. |
KoreaWAMISCollector ¶
Bases: BaseCollector
Collect water data from Korea WAMIS Open API.
Supports water-level, discharge, water-quality, and dam-storage
observations. Results are normalised to WaterQualitySample
records with source = DataSource.KOREA_WAMIS.
fetch_raw ¶
fetch_raw(station_id: str | None = None, basin: str | None = None, parameter: str = 'water_level', start_date: str | None = None, end_date: str | None = None, **kwargs: Any) -> list[dict]
Fetch raw observation data from the WAMIS Open API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
station_id
|
str | None
|
WAMIS station code. |
None
|
basin
|
str | None
|
Basin name in English (e.g. |
None
|
parameter
|
str
|
One of |
'water_level'
|
start_date
|
str | None
|
Start date in ISO format ( |
None
|
end_date
|
str | None
|
End date in ISO format ( |
None
|
**kwargs
|
Any
|
Additional keyword arguments forwarded to the HTTP request. |
{}
|
Returns:
| Type | Description |
|---|---|
list[dict]
|
Raw observation records. Returns an empty list when the upstream API is unreachable or no data matches. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If parameter is not one of the supported types. |
normalise ¶
Normalise raw WAMIS data into WaterQualitySample records.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
list[dict]
|
Raw records as returned by |
required |
Returns:
| Type | Description |
|---|---|
list[WaterQualitySample]
|
Unified water-quality sample records. |
NOAANWPSCollector ¶
Bases: BaseCollector
fetch_raw ¶
fetch_raw(*, lid: str | None = None, bbox: tuple[float, float, float, float] | None = None, srid: str = 'EPSG_4326', catfim: bool = False, **_: Any) -> Any
Fetch NWPS payload for one lid or enumerate a list of lids discovered by bbox. The first 5 LIDs will be iterated through _build_combined_data_dictionary
normalise ¶
Convert NWPS observed entries into StreamflowReading records.
OpenMeteoCollector ¶
Bases: BaseCollector
Fetch weather, climate reanalysis, and river-discharge data from Open-Meteo.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mode
|
str
|
|
'weather'
|
Example
collector = OpenMeteoCollector(mode="weather") records = collector.collect( ... latitude=25.03, longitude=121.57, ... start_date="2023-01-01", end_date="2023-12-31", ... daily=["temperature_2m_mean", "precipitation_sum"], ... )
fetch_raw ¶
fetch_raw(*, latitude: float, longitude: float, start_date: str | None = None, end_date: str | None = None, daily: list[str] | None = None, hourly: list[str] | None = None, forecast_days: int = 7, models: str | None = None) -> dict
Call the Open-Meteo API and return the raw JSON response.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
latitude
|
float
|
Site coordinates. |
required |
longitude
|
float
|
Site coordinates. |
required |
start_date
|
str | None
|
ISO-8601 date strings (required for archive mode). |
None
|
end_date
|
str | None
|
ISO-8601 date strings (required for archive mode). |
None
|
daily
|
list[str] | None
|
Daily variables to request (e.g. |
None
|
hourly
|
list[str] | None
|
Hourly variables (e.g. |
None
|
forecast_days
|
int
|
Number of forecast days (only for |
7
|
models
|
str | None
|
Weather-mode reanalysis to read through the |
None
|
normalise ¶
Convert Open-Meteo JSON into unified WaterQualitySample records.
Weather / climate variables are stored as WaterQualitySample with
parameter set to the variable name (e.g. precipitation_sum).
PegelonlineCollector ¶
Bases: BaseCollector
Collect recent water-level and discharge readings from PEGELONLINE.
PEGELONLINE exposes raw measurements for only the most recent 31 days. Stations are addressed by UUID because station names and numbers are not guaranteed to be unique or stable.
stations ¶
stations(*, bbox: tuple[float, float, float, float] | None = None, variable: str | None = None, max_items: int | None = None) -> list[Station]
All PEGELONLINE gauges (stations.json?includeTimeseries=true).
The API has no spatial filter, so bbox is applied client side.
variables comes from the advertised timeseries codes (W water
level, Q discharge).
fetch_raw ¶
fetch_raw(station_id: str | None = None, timeseries: str | Sequence[str] | None = None, days: int = 30, start: str | None = None, end: str | None = None, **kwargs: Any) -> dict[str, Any]
Fetch station metadata and recent W/Q measurements.
Args:
station_id: PEGELONLINE station UUID.
timeseries: W (water level), Q (discharge), or both.
days: Relative history window when start is omitted (1-31).
start: Optional API timestamp or ISO-8601 duration.
end: Optional API timestamp.
normalise ¶
Convert PEGELONLINE W/Q measurements to AquaScope records.
PolandIMGWCollector ¶
PolandIMGWCollector(client: CachedHTTPClient | None = None, cache_dir: Path | None = None, timeout: float = 120.0)
Bases: BaseCollector
IMGW-PIB river gauges: live network state and the daily archive from 1951.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
CachedHTTPClient
|
Used for the live API. Injected for testing. |
None
|
cache_dir
|
Path
|
Where archive zips are kept between runs (default |
None
|
timeout
|
float
|
Per-download timeout for archive zips, seconds. |
120.0
|
fetch_live ¶
The current state of every station, one request, cached for the run.
stations ¶
stations(*, bbox: tuple[float, float, float, float] | None = None, variable: str | None = None, max_items: int | None = None) -> list[Station]
The network from the live API: every station carries coordinates.
variables reflects what the station is reporting now; the
archive may hold more (a gauge whose discharge rating lapsed still
has decades of discharge behind it).
fetch_raw ¶
fetch_raw(variable: str = 'discharge', station_ids: Iterable[str | int] | None = None, bbox: tuple[float, float, float, float] | None = None, start: str | date | None = None, end: str | date | None = None, max_stations: int | None = None, latest_only: bool = False, **kwargs: Any) -> list[dict[str, Any]]
Daily rows for one variable from the archive, or the live reading with latest_only.
start/end select archive files by hydrological year and month,
then rows by calendar date; the default window is the last 365 days.
Files for years not yet published are skipped, so a window reaching
into the current hydrological year simply stops at the last October.
normalise ¶
Discharge to :class:StreamflowReading (m3/s), stage to :class:WaterLevelReading
(metres above the gauge datum), water temperature to :class:WaterQualitySample (°C).
SDG6Collector ¶
Bases: BaseCollector
Collect SDG 6 indicator data per country/year from the UN-Stats API.
fetch_raw ¶
fetch_raw(indicator_codes: list[str] | None = None, country_codes: str | None = None, page_size: int = 200, **kwargs) -> list[dict]
Fetch SDG 6 indicator records.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
indicator_codes
|
list[str] | None
|
e.g. ["6.4.2", "6.4.1"]. Defaults to all 9 SDG 6 indicators. |
None
|
country_codes
|
str | None
|
Comma-separated ISO3 or M49 numeric codes, e.g. "USA,DEU,IND". Omit to return data for all countries. |
None
|
page_size
|
int
|
Records per API page (max 5000 per UN docs). |
200
|
SouthAfricaDWSCollector ¶
Bases: BaseCollector
Collect verified river discharge and water level from South Africa DWS.
discharge requests the DWS daily mean series (D_AVG_FR).
water_level requests point observations (COR_LEVEL).
fetch_raw ¶
fetch_raw(station_id: str, variable: str = 'discharge', start_date: str | date | datetime | None = None, end_date: str | date | datetime | None = None, days: int | None = None, use_cache: bool = False, **kwargs: Any) -> list[dict[str, Any]]
Fetch and parse one DWS river series.
Parameters use the agency station code without the DWS 100.00
series suffix, for example C1H001. A supplied suffix is accepted
and normalised so it is never duplicated.
Caching is disabled by default because DWS can return an application error document with HTTP 200; callers may opt in once the upstream service is known to be healthy.
TaiwanCivilIoTCollector ¶
Bases: BaseCollector
Collect real-time water resource data from Taiwan's Civil IoT SensorThings API.
The entity parameter is consumed by :meth:fetch_raw, not by
__init__; see that method's docstring for valid values.
fetch_raw ¶
fetch_raw(entity: str = 'Datastreams', top: int = 100, expand: str | None = None, start_date: str | None = None, end_date: str | None = None, **kwargs) -> list[dict]
Fetch SensorThings entities.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entity
|
str
|
|
'Datastreams'
|
top
|
int
|
Max items per page. |
100
|
expand
|
str
|
OData $expand clause. If not given, one is built from
|
None
|
start_date
|
str
|
ISO date string |
None
|
end_date
|
str
|
ISO date string |
None
|
normalise ¶
Normalise SensorThings Datastreams with their latest Observation.
TaiwanCWACollector ¶
Bases: BaseCollector
Collect daily climate observations from Taiwan CWA stations via CODIS.
stations ¶
stations(*, bbox: tuple[float, float, float, float] | None = None, variable: str | None = None, max_items: int | None = None) -> list[Station]
CWA station catalog from CODIS station_list (manned, agricultural, automatic).
Every station reports precipitation; the manned (cwb) network also
carries the full climate set. extra["attribute"] keeps the CODIS
group (cwb / agr / auto) so callers can pick long-archive
stations.
fetch_raw ¶
fetch_raw(station_ids: list[str] | str | None = None, start: str | None = None, end: str | None = None, stn_type: str | None = None, **kwargs) -> list[dict]
Fetch daily climate records for one or more stations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
station_ids
|
list[str] | str
|
CWA station identifiers (e.g. |
None
|
start
|
str
|
Inclusive ISO dates ( |
None
|
end
|
str
|
Inclusive ISO dates ( |
None
|
stn_type
|
str
|
CODIS station attribute. By default it follows from the station id
(:func: |
None
|
TaiwanDataGovCollector ¶
TaiwanDataGovCollector(dataset_id: str = DATASET_WATER_LEVEL, client: CachedHTTPClient | None = None)
Bases: BaseCollector
Collect real-time water level data from Taiwan's open government data platform (data.gov.tw).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset_id
|
str
|
WRA Open Data UUID. Use :data: |
DATASET_WATER_LEVEL
|
fetch_raw ¶
Fetch records from the WRA Open Data API for the configured dataset.
The API returns the full dataset in one response; offset and an
optional limit are applied client-side. By default all records are
returned.
TaiwanMOENVCollector ¶
TaiwanMOENVCollector(api_key: str = '', dataset_id: str = RIVER_WQ_DATASET, client: CachedHTTPClient | None = None)
Bases: BaseCollector
Collect river water-quality monitoring data from Taiwan MOENV.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_key
|
str
|
Free key obtained at https://data.moenv.gov.tw/en/apikey |
''
|
dataset_id
|
str
|
Dataset identifier (default: river water quality |
RIVER_WQ_DATASET
|
fetch_raw ¶
Page through MOENV open-data endpoint and return raw records.
TaiwanWRAGroundwaterCollector ¶
TaiwanWRAGroundwaterCollector(statistic: str = 'average', na_value: float | None = None, with_metadata: bool = True, client: CachedHTTPClient | None = None)
Bases: BaseCollector
Collect annual groundwater-level statistics from WRA.
Source: WRA annual-groundwater dataset (GROUNDWATER_ANNUAL_DATASET),
~992 wells nationwide, one record per well per year (1992-present), with
annual average / maximum-daily / minimum-daily water levels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
statistic
|
str
|
Which annual statistic to emit as |
'average'
|
na_value
|
float | None
|
How to represent missing values (WRA's |
None
|
with_metadata
|
bool
|
When |
True
|
TaiwanWRAGroundwaterDailyCollector ¶
TaiwanWRAGroundwaterDailyCollector(zones: Sequence[str] | None = None, stations: Sequence[str] | None = None, start: str | date | None = None, end: str | date | None = None, aggregate: str = 'monthly', window_years: int = 5, with_metadata: bool = True, client: CachedHTTPClient | None = None)
Bases: BaseCollector
Collect DAILY groundwater-level series from the WRA gweb HydroInfo portal.
Unlike :class:TaiwanWRAGroundwaterCollector (annual statistics from the
open-data API), this collector reaches the sub-annual series the open-data
API does not expose, which is what drought-propagation methods (monthly
SGI, SPI/SPEI lag analysis) require. Per-well daily records span roughly
2005-2025, with the Zhuoshui (Choushui) fan back to 1997.
The portal throttles request bursts and resets connections, so this
collector rate-limits and caches every POST. A full national pull is
thousands of requests; scope with zones or stations for a focused
study. Re-runs are served from cache.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zones
|
list[str] | None
|
Aquifer zones to include, by English alias (e.g. |
None
|
stations
|
list[str] | None
|
Explicit station identifiers (e.g. |
None
|
start
|
str | date | None
|
Clip the date range ( |
None
|
end
|
str | date | None
|
Clip the date range ( |
None
|
aggregate
|
str
|
|
'monthly'
|
window_years
|
int
|
Chunk size (years) for the windowed chart pulls. Default 5. |
5
|
with_metadata
|
bool
|
When |
True
|
Notes
water_level_m carries the WRA-reported groundwater level relative to its
datum (Taiwan Vertical Datum), NOT depth below ground surface; values are
signed. Verify the datum per aquifer before interpreting drawdown.
TaiwanWRAReservoirCollector ¶
TaiwanWRAWaterLevelCollector ¶
Bases: BaseCollector
Collect real-time water-level readings from WRA river stations. Updated every 10 minutes at source.
TaiwanWRAFhyCollector ¶
Bases: BaseCollector
Collect real-time hydrological data from the WRA 防災資訊網 (Fhy) API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_type
|
str
|
One of |
'water'
|
TaiwanWRAIoTCollector ¶
Bases: BaseCollector
Collect real-time hydrological data from the WRA IoT open-data API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_type
|
str
|
Currently only |
'groundwater'
|
fetch_raw ¶
Fetch the station list (each with a nested Measurements array).
CachedHTTPClient.get_json strips any BOM / leading whitespace and
checks Content-Type before parsing, so a non-JSON body (e.g. an HTML
error page from a stale path) surfaces as ValueError with a
preview of the response rather than an opaque JSONDecodeError.
normalise ¶
Flatten each station's nested Measurements into samples.
One WaterQualitySample is emitted per (station, measurement)
pair — today that's one reading per station, but the API models it
as a list so a station could in principle report more than one
physical quantity in the future.
UKEACollector ¶
Bases: BaseCollector
Collect readings from the UK Environment Agency hydrology API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
CachedHTTPClient | None
|
Optional preconfigured HTTP client used for API requests. If not passed, a default client is used. |
None
|
Initialise the collector.
stations ¶
stations(*, bbox: tuple[float, float, float, float] | None = None, variable: str | None = None, max_items: int | None = None) -> list[Station]
EA Hydrology API station catalog (id/stations.json).
The API filters by observedProperty and by lat/long bounds; each
item lists every observed property at the site, which becomes
variables. dateOpened / dateClosed become the period.
fetch_raw ¶
fetch_raw(collection: str | None = '15min', observed_property: str | None = None, measure: str | None = None, station: str | None = None, station_wiski_id: str | None = None, bbox: str | None = None, min_date: str | None = None, max_date: str | None = None, days: int | None = None, limit: int = 10000, max_items: int | None = 2000, **kwargs) -> list[dict]
Fetch readings from the UK Environment Agency Hydrology API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
collection
|
str | None
|
Frequency of data collection. Supported values are |
'15min'
|
observed_property
|
str | None
|
Normalised observed property name. Supported values:
|
None
|
measure
|
str | None
|
Exact measure identifier. When supplied, the collector uses the measure directly and ignores station and collection filters. |
None
|
station
|
str | None
|
Station SUID, used to collect data from a specific station. A 36-character GUID-style identifier. |
None
|
station_wiski_id
|
str | None
|
WISKI station identifier, primarily used to differentiate between co-located stations that share the same station SUID. |
None
|
bbox
|
str | None
|
Bounding box for location-based queries.
Expressed as |
None
|
min_date
|
str | None
|
Inclusive lower bound for the requested date range.
If not accompanied by a max_date,
data from the next |
None
|
max_date
|
str | None
|
Inclusive upper bound for the requested date range.
If the max_date is in the future, the value defaults to today's date.
If not accompanied by a min_date,
data from the previous |
None
|
days
|
int | None
|
Relative lookback window in days used when explicit date range is not used absent. If there is no date range and no days value passed, data from the last 30 days are passed. |
None
|
limit
|
int
|
Number of records requested per page from the API. |
10000
|
max_items
|
int | None
|
Maximum number of records to return after the metadata row is prepended.
|
2000
|
Returns:
| Type | Description |
|---|---|
list[dict]
|
Raw API items with a prepended metadata dictionary used by
:meth: |
normalise ¶
normalise(raw: list[dict]) -> Sequence[WaterQualitySample] | Sequence[WaterLevelReading] | Sequence[StreamflowReading]
Convert raw UK EA readings into AquaScope schema objects.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
list[dict]
|
Raw payload returned by :meth: |
required |
Returns:
| Type | Description |
|---|---|
Sequence[WaterQualitySample] | Sequence[WaterLevelReading] | Sequence[StreamflowReading]
|
Normalised water-quality, water-level, or streamflow records. If the observed property requested does not map to a schema object, or there is no raw data available, an empty list is returned. |
USGSCollector ¶
USGSCollector(api_key: str | None = None, client: CachedHTTPClient | None = None, *, lookup_catchment_area: bool = True)
Bases: BaseCollector
Collect daily-value water data from USGS via the Water Data OGC API (v1).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_key
|
str | None
|
USGS API key for higher rate limits (get one at
https://api.waterdata.usgs.gov/signup/). If omitted, the collector
reads the |
None
|
keyed
property
¶
True when a real USGS API key is set (not the keyless DEMO_KEY placeholder).
fetch_raw ¶
fetch_raw(collection: str = 'daily', datetime_range: str | None = None, days: int | None = None, limit: int = 10000, bbox: str | None = None, max_items: int | None = 2000, **kwargs) -> list[dict]
Fetch features from a USGS Water Data OGC collection (v1).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
collection
|
str
|
|
'daily'
|
datetime_range
|
str
|
Explicit ISO 8601 interval |
None
|
days
|
int
|
Last N days from now (UTC). Defaults to 30 when |
None
|
limit
|
int
|
Max features per page (the API allows up to 50,000). USGS advises one page per query: every further page re-runs the query. |
10000
|
bbox
|
str
|
Bounding box filter |
None
|
max_items
|
int
|
Hard cap on total records fetched (across all pages). Keeps response
times predictable. |
2000
|
**kwargs
|
Filters: |
{}
|
stations ¶
stations(*, bbox: tuple[float, float, float, float] | None = None, variable: str | None = None, max_items: int | None = 20000) -> list[Station]
USGS monitoring locations with daily-value time series.
Built from the keyless OGC time-series-metadata collection (one
feature per daily series, with geometry, parameter code and period of
record), joined to monitoring-locations for names. Without a
bbox this walks the whole national network; keep max_items
unless you mean it.
WaPORCollector ¶
Bases: BaseCollector
Collect satellite-based ET data from FAO WaPOR v3.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
CachedHTTPClient | None
|
HTTP client instance. A default is created if None. |
None
|
References
FAO. (2024). WaPOR v3. https://www.fao.org/in-action/remote-sensing-for-water-productivity/
fetch_raw ¶
fetch_raw(bbox: tuple[float, float, float, float] | None = None, start_date: str = '2020-01-01', end_date: str = '2020-12-31', variable: str = 'RET', **kwargs: Any) -> list[dict]
Fetch raw WaPOR raster catalogue/summary data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bbox
|
tuple[float, float, float, float] | None
|
Bounding box as |
None
|
start_date
|
str
|
ISO date string for start of period. |
'2020-01-01'
|
end_date
|
str
|
ISO date string for end of period. |
'2020-12-31'
|
variable
|
str
|
WaPOR variable code ( |
'RET'
|
Returns:
| Type | Description |
|---|---|
list[dict]
|
Raw API response records. |
normalise ¶
Convert raw WaPOR response into WaPORObservation records.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
list[dict]
|
Records from |
required |
Returns:
| Type | Description |
|---|---|
Sequence[WaPORObservation]
|
Normalised WaPOR observations. |
WQPCollector ¶
Bases: BaseCollector
Collect discrete water quality data from the US Water Quality Portal.
Supports filtering by state, county, characteristic (parameter), date range, and bounding box.
fetch_raw ¶
fetch_raw(state_code: str | None = None, characteristic_name: str | Sequence[str] | None = None, start_date: str | None = None, end_date: str | None = None, bbox: str | None = None, max_results: int = 1000, site_id: str | Sequence[str] | None = None, **kwargs) -> list[dict]
Fetch water quality results from WQP.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state_code
|
str | None
|
e.g. |
None
|
characteristic_name
|
str | Sequence[str] | None
|
e.g. |
None
|
site_id
|
str | Sequence[str] | None
|
WQP monitoring location id(s), e.g. |
None
|
start_date
|
str | None
|
|
None
|
end_date
|
str | None
|
|
None
|
bbox
|
str | None
|
Bounding box: |
None
|
max_results
|
int
|
Limit number of results (WQP default returns CSV). |
1000
|
AI engine: methodology recommender¶
aquascope.ai_engine ¶
AI-powered research methodology recommendation engine.
AgentResult
dataclass
¶
AgentResult(challenge_spec: ChallengeSpec, model_used: str = '', forecast: DataFrame | None = None, risk_assessment: dict | None = None, status: dict | None = None, anomalies: DataFrame | None = None, explanation: str = '', steps: list[str] = list())
Result of an end-to-end agent run.
HydroAgent ¶
Orchestrator that parses a natural-language query and executes the corresponding challenge.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default_model
|
str | None
|
Override the auto-recommended model. If |
None
|
Example
agent = HydroAgent() result = agent.solve("Drought monitoring near Sahel at lat 15, lon 0") print(result.explanation)
solve ¶
solve(query: str, data: DataFrame | None = None, extra_data: dict[str, DataFrame] | None = None) -> AgentResult
Parse query, load data, pick model, and run the challenge.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
Natural-language challenge description. |
required |
data
|
DataFrame | None
|
Primary data (discharge / precipitation). If |
None
|
extra_data
|
dict[str, DataFrame] | None
|
Additional named DataFrames (e.g. |
None
|
Returns:
| Type | Description |
|---|---|
AgentResult
|
|
ResearchMethodology
dataclass
¶
ResearchMethodology(id: str, name: str, category: str, description: str, applicable_parameters: list[str] = list(), data_requirements: list[str] = list(), typical_scale: str = '', complexity: str = '', references: list[str] = list(), tags: list[str] = list())
Describes a single research methodology applicable to water studies.
ModelRecommendation
dataclass
¶
A single model recommendation.
ModelRecommender ¶
Recommend predictive models for a given challenge type and task.
Example
rec = ModelRecommender() picks = rec.recommend("flood", "forecast") picks[0].model_id 'prophet'
recommend ¶
recommend(challenge_type: str, task_type: str = 'forecast', top_k: int = 3) -> list[ModelRecommendation]
Return ranked model recommendations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
challenge_type
|
str
|
One of |
required |
task_type
|
str
|
Task within the challenge: |
'forecast'
|
top_k
|
int
|
Maximum number of recommendations to return. |
3
|
Returns:
| Type | Description |
|---|---|
list[ModelRecommendation]
|
|
ChallengePlanner ¶
Parse natural-language descriptions into structured challenge specs.
Example
planner = ChallengePlanner() spec = planner.parse("Forecast flooding on the Niger River at lat 13.5, lon 2.1") spec.challenge_type 'flood'
parse ¶
Parse a natural-language query into a ChallengeSpec.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
Free-text description of the challenge. |
required |
Returns:
| Type | Description |
|---|---|
ChallengeSpec
|
Structured challenge with type, variables, and location. |
ChallengeSpec
dataclass
¶
ChallengeSpec(challenge_type: str = 'unknown', variables: list[str] = list(), latitude: float | None = None, longitude: float | None = None, location_name: str | None = None, forecast_days: int = 7, raw_query: str = '', confidence: float = 0.0)
Structured representation of a parsed challenge request.
DatasetProfile
dataclass
¶
DatasetProfile(parameters: list[str] = list(), n_records: int = 0, n_stations: int = 0, time_span_years: float = 0.0, geographic_scope: str = '', data_sources: list[str] = list(), research_goal: str = '', keywords: list[str] = list())
Summary of a collected dataset, used as input to the recommender.
Recommendation
dataclass
¶
A single methodology recommendation with a relevance score.
RecommendationResult
dataclass
¶
RecommendationResult(recommendations: list[Recommendation], mode: str = 'rule_based', provider: str = '', model: str = '', error: str = '')
Recommendations plus how they were produced.
mode is "llm" when a language model actually answered, and
"rule_based" when the heuristic scorer produced the list. When the
LLM was requested but could not be used, error holds a human-readable
reason so callers can show it instead of silently degrading.
get_methodology ¶
Look up a methodology by ID.
search_methodologies ¶
search_methodologies(parameters: list[str] | None = None, category: str | None = None, tags: list[str] | None = None, scale: str | None = None) -> list[ResearchMethodology]
Filter the catalogue by parameters, category, tags, or scale.
recommend ¶
Return the top-k methodology recommendations for the given dataset profile.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
profile
|
DatasetProfile
|
|
required |
top_k
|
int
|
|
5
|
min_score
|
float
|
Minimum relevance score to include. |
20.0
|
Returns:
| Type | Description |
|---|---|
list[Recommendation] sorted by descending score.
|
|
recommend_with_llm ¶
recommend_with_llm(profile: DatasetProfile, top_k: int = 5, model: str = 'gpt-4o-mini', api_key: str | None = None, base_url: str | None = None, timeout: float = 120.0) -> list[Recommendation]
Use an LLM to provide more nuanced methodology recommendations.
Falls back to rule-based if the LLM call fails. Use
:func:recommend_with_llm_detailed when you need to know whether the LLM
actually answered, and why it did not.
recommend_with_llm_detailed ¶
recommend_with_llm_detailed(profile: DatasetProfile, top_k: int = 5, model: str = 'gpt-4o-mini', api_key: str | None = None, base_url: str | None = None, timeout: float = 120.0) -> RecommendationResult
Use an LLM for nuanced methodology recommendations, reporting what happened.
Unlike :func:recommend_with_llm, this never degrades silently: on any
failure it still returns rule-based recommendations, but mode is
"rule_based" and error explains why the LLM was not used, so a UI
or CLI can show the reason to the user.
Supported providers (detected from base_url): - OpenAI (base_url=None or api.openai.com) - HuggingFace serverless inference (router.huggingface.co) — free tier - Groq (api.groq.com) — free tier - Ollama local (localhost) — uses native /api/chat to avoid openai-client quirks - Any other OpenAI-compatible endpoint
Hydrological analysis¶
Flood-frequency analysis, baseflow separation, rating curves, signatures.
aquascope.hydrology ¶
AquaScope hydrology module.
Standard hydrological analysis tools:
- Flow duration curves and low-flow statistics (Q95, 7Q10, 30Q5)
- Baseflow separation (Lyne–Hollick, Eckhardt digital filters)
- Recession analysis (segment identification + MRC fitting)
- Flood frequency analysis (GEV, Log-Pearson Type III)
- Stage-discharge rating curves (power-law fit, segmented curves, shift detection)
Quick start::
from aquascope.hydrology import flow_duration_curve, lyne_hollick, recession_analysis, fit_gev
fdc = flow_duration_curve(discharge_series)
print(f"Q95 = {fdc.percentiles[95]:.2f} m³/s")
bf = lyne_hollick(discharge_series)
print(f"BFI = {bf.bfi:.2f}")
rec = recession_analysis(discharge_series)
print(f"Recession constant = {rec.recession_constant:.1f} days")
ffa = fit_gev(discharge_series)
print(f"100-year flood = {ffa.return_periods[100]:.1f} m³/s")
BaseflowResult
dataclass
¶
Result of baseflow separation.
Attributes:
| Name | Type | Description |
|---|---|---|
df |
DataFrame
|
DataFrame with |
bfi |
float
|
Baseflow Index — ratio of total baseflow to total discharge. |
method |
str
|
Name of the filter used. |
BudykoResult
dataclass
¶
BudykoResult(aridity_index: float | ndarray, predicted: dict[str, float | ndarray], observed_evaporative_ratio: float | ndarray | None = None, observed_deviation: dict[str, float | ndarray] | None = None, aridity_grid: ndarray = (lambda: _DEFAULT_ARIDITY_GRID.copy())(), curves: dict[str, ndarray] = dict())
Predicted evaporative ratios under the Budyko framework.
Attributes:
| Name | Type | Description |
|---|---|---|
aridity_index |
float | ndarray
|
Aridity index (PET / P) at the query point(s): a float for scalar inputs, an array of the input shape otherwise. |
predicted |
dict[str, float | ndarray]
|
Predicted evaporative ratio (ET / P) per requested curve, evaluated
at |
observed_evaporative_ratio |
(float | ndarray, optional)
|
Observed evaporative ratio (ET / P) when observed_et or observed_runoff was given. |
observed_deviation |
(dict[str, float | ndarray], optional)
|
Observed ratio minus predicted ratio per curve; positive means the catchment sits above the curve (more evaporative than predicted). |
aridity_grid |
ndarray
|
The aridity domain the curves were evaluated over: the canonical
|
curves |
dict[str, ndarray]
|
Predicted evaporative ratio per requested curve over |
EMAResult
dataclass
¶
EMAResult(return_periods: dict[int, float] = dict(), distribution: str = '', params: tuple = (), annual_max: Series | None = None, confidence_intervals: dict[int, tuple[float, float]] = dict(), n_bootstrap: int | None = None, n_bootstrap_discarded: int | None = None, n_censored: int = 0, n_observed: int = 0, weighted_skew: float | None = None, low_outlier_threshold: float | None = None)
Bases: FloodFreqResult
Result of Expected Moments Algorithm flood frequency analysis.
Extends :class:FloodFreqResult with censoring and EMA-specific fields.
Attributes:
n_censored: Number of censored (zero-flow / low-outlier) observations.
n_observed: Number of non-censored observations.
weighted_skew: Weighted skew coefficient (station + regional).
None when no regional skew was supplied.
low_outlier_threshold: MGB low-outlier threshold (real-space).
None when no outliers were detected.
FloodFreqResult
dataclass
¶
FloodFreqResult(return_periods: dict[int, float] = dict(), distribution: str = '', params: tuple = (), annual_max: Series | None = None, confidence_intervals: dict[int, tuple[float, float]] = dict(), n_bootstrap: int | None = None, n_bootstrap_discarded: int | None = None)
Result of flood frequency analysis.
Attributes:
| Name | Type | Description |
|---|---|---|
return_periods |
dict[int, float]
|
Mapping of return period (years) → estimated discharge. |
distribution |
str
|
Name of the fitted distribution. |
params |
tuple
|
Distribution parameters (shape, loc, scale). |
annual_max |
Series | None
|
The annual maximum series used for fitting. |
confidence_intervals |
dict[int, tuple[float, float]]
|
Optional mapping of return period → (lower, upper) 90 % CI. |
n_bootstrap |
int | None
|
Number of bootstrap resamples drawn (when CI estimation is enabled). |
n_bootstrap_discarded |
int | None
|
Number of bootstrap resample fits discarded due to parameter bounds. |
GoodnessOfFitResult
dataclass
¶
GoodnessOfFitResult(statistic: float = 0.0, p_value: float = 1.0, test_name: str = '', distribution: str = '', reject_h0: bool = False)
Result of a goodness-of-fit test.
Attributes:
statistic: Test statistic value.
p_value: Associated p-value.
test_name: Name of the test.
distribution: Distribution that was tested.
reject_h0: True if H₀ (data follows distribution) is rejected at α = 0.05.
NonStationaryGEVResult
dataclass
¶
NonStationaryGEVResult(loc_intercept: float = 0.0, loc_trend: float = 0.0, scale: float = 1.0, shape: float = 0.0, return_levels: dict[float, ndarray] = dict(), years: ndarray = (lambda: np.array([]))(), aic: float = 0.0, bic: float = 0.0, trend_significant: bool = False, lr_statistic: float = 0.0, p_value: float = 1.0, aic_stationary: float = 0.0, stationary_params: tuple[float, float, float] = (0.0, 0.0, 1.0))
Result of non-stationary GEV fit.
Attributes:
loc_intercept: Intercept of the linear location model.
loc_trend: Trend in the location parameter (per year).
scale: Scale parameter.
shape: Shape parameter (scipy sign convention).
return_levels: Mapping of return period → array of return levels over time.
years: The year values used for fitting.
aic: Akaike information criterion.
bic: Bayesian information criterion.
trend_significant: True if the trend p-value < 0.05 (likelihood-ratio test).
lr_statistic, p_value: The likelihood-ratio statistic and its chi-squared p-value.
aic_stationary: AIC of the stationary GEV fitted by the same likelihood.
stationary_params: (shape, loc, scale) of that stationary GEV.
RegionalResult
dataclass
¶
RegionalResult(growth_curve: dict[float, float] = dict(), index_flood: dict[str, float] = dict(), regional_return_levels: dict[str, dict[float, float]] = dict(), discordancy: dict[str, float] = dict(), heterogeneity: float = 0.0)
Result of regional frequency analysis.
Attributes: growth_curve: Mapping of return period → growth factor. index_flood: Mapping of site id → index flood (mean annual max). regional_return_levels: Mapping of site id → {return period → level}. discordancy: Mapping of site id → discordancy statistic Dᵢ. heterogeneity: Heterogeneity H statistic.
FDCResult
dataclass
¶
Result of a flow duration curve analysis.
Attributes:
| Name | Type | Description |
|---|---|---|
exceedance |
ndarray
|
Exceedance probability array (0–100 %). |
discharge |
ndarray
|
Sorted discharge values (descending). |
percentiles |
dict[float, float]
|
Mapping of exceedance % → discharge value (e.g. |
RatingCurveResult
dataclass
¶
RatingCurveResult(a: float, b: float, h0: float, r_squared: float, rmse: float, n_points: int, residuals: ndarray, stage_range: tuple[float, float], segments: list[RatingSegment] | None = None)
Result of rating curve fitting.
Attributes:
a: Power-law coefficient.
b: Power-law exponent.
h0: Stage offset (datum correction).
r_squared: Coefficient of determination.
rmse: Root mean squared error.
n_points: Number of stage-discharge pairs used.
residuals: Array of residuals (observed - predicted).
stage_range: Tuple of (min_stage, max_stage).
segments: Segment parameters for segmented curves, or None.
RatingSegment
dataclass
¶
A segment of a segmented rating curve.
Attributes: stage_min: Lower bound of the segment stage range. stage_max: Upper bound of the segment stage range. a: Power-law coefficient. b: Power-law exponent. h0: Stage offset (datum correction). r_squared: Coefficient of determination for the segment.
RecessionResult
dataclass
¶
RecessionResult(segments: list[RecessionSegment] = list(), recession_constant: float = 0.0, r_squared: float = 0.0, half_life_days: float = 0.0)
Result of recession analysis.
Attributes:
| Name | Type | Description |
|---|---|---|
segments |
list[RecessionSegment]
|
List of identified recession segments. |
recession_constant |
float
|
Fitted exponential decay constant k in Q(t) = Q₀·e^(−t/k). |
r_squared |
float
|
R² of the master recession curve fit. |
half_life_days |
float
|
Time in days for discharge to halve (k·ln(2)). |
RecessionSegment
dataclass
¶
A single recession segment.
Attributes:
| Name | Type | Description |
|---|---|---|
start |
Timestamp
|
Start timestamp. |
end |
Timestamp
|
End timestamp. |
discharge |
ndarray
|
Discharge values during the recession. |
SignatureReport
dataclass
¶
SignatureReport(mean_flow: float, median_flow: float, q5: float, q95: float, q5_q95_ratio: float, cv: float, iqr: float, high_flow_frequency: float, high_flow_duration: float, q_peak_mean: float, low_flow_frequency: float, low_flow_duration: float, baseflow_index: float, zero_flow_fraction: float, peak_month: int, seasonality_index: float, rising_limb_density: float, flashiness_index: float, mean_recession_constant: float, fdc_slope: float = 0.0, runoff_ratio: float | None = None, elasticity: float | None = None)
Complete set of hydrological signatures for a streamflow record.
Attributes are grouped by the aspect of the flow regime they describe.
Fields set to None require optional inputs (e.g. precipitation).
eckhardt ¶
Separate baseflow using the Eckhardt two-parameter digital filter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Daily discharge series with a DatetimeIndex. |
required |
alpha
|
float
|
Recession constant (typically 0.95–0.99). |
0.98
|
bfi_max
|
float
|
Maximum baseflow index — depends on aquifer type: - 0.80 for perennial streams with porous aquifers - 0.50 for ephemeral streams with porous aquifers - 0.25 for perennial streams with hard-rock aquifers |
0.8
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class:`BaseflowResult` with separated components and BFI.
|
|
lyne_hollick ¶
Separate baseflow using the Lyne–Hollick recursive digital filter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Daily discharge series with a DatetimeIndex. |
required |
alpha
|
float
|
Filter parameter (0 < α < 1). Higher values yield less baseflow. Default 0.925 is the value recommended by Nathan & McMahon (1990). |
0.925
|
n_passes
|
int
|
Number of forward/backward filter passes (typically 3). |
3
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class:`BaseflowResult` with separated components and BFI.
|
|
ukih ¶
Separate baseflow using the UKIH smoothed-minima (sliding-interval) method.
The record is divided into non-overlapping blocks of block_size
days. The minimum discharge in each block is a candidate turning
point if 0.9 times its value is less than both neighbouring block
minima. Baseflow is then linearly interpolated between turning
points and capped at the observed discharge.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Daily discharge series with a DatetimeIndex. |
required |
block_size
|
int
|
Number of days per non-overlapping block (N). Default 5, as recommended by the Institute of Hydrology (1980). |
5
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class:`BaseflowResult` with separated components and BFI.
|
|
References
Institute of Hydrology (1980). Low Flow Studies Report No. 1. Wallingford, UK.
anderson_darling_test ¶
Anderson-Darling goodness-of-fit test for a fitted distribution.
Parameters:
data: Observed sample.
distribution: Distribution name (e.g. "gev", "gumbel").
params: Distribution parameters as accepted by the scipy distribution.
Returns:
A :class:GoodnessOfFitResult.
coverage_probability ¶
coverage_probability(discharge: Series, distribution: str = 'gev', ci_level: float = 0.9, n_splits: int = 10, n_boot: int = 200) -> float
Estimate the coverage probability of confidence intervals.
Split data into n_splits folds, compute bootstrap CIs on each training set, and check what fraction of test observations fall within those CIs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Annual maximum discharge series. |
required |
distribution
|
str
|
Distribution key. |
'gev'
|
ci_level
|
float
|
Nominal confidence level (default 0.90). |
0.9
|
n_splits
|
int
|
Number of cross-validation folds (default 10). |
10
|
n_boot
|
int
|
Number of bootstrap samples per fold (default 200). |
200
|
Returns:
| Type | Description |
|---|---|
float
|
Observed coverage probability (0–1). |
cramer_von_mises_test ¶
Cramér–von Mises goodness-of-fit test.
Parameters: data: Observed sample. distribution: Distribution name. params: Distribution parameters.
Returns:
A :class:GoodnessOfFitResult.
expected_moments_algorithm ¶
expected_moments_algorithm(annual_max: Series | ndarray, *, perception_thresholds: list[tuple[float, float]] | None = None, zero_threshold: float = 0.0, regional_skew: float | None = None, regional_skew_mse: float = 0.302, return_periods: list[int] | None = None) -> EMAResult
Expected Moments Algorithm (EMA) for LP3 flood frequency analysis.
Implements the EMA procedure of Cohn et al. (1997) for incorporating censored observations (zero-flow years, low outliers, historical floods) into the LP3 parameter estimation. This is the preferred method in USGS Bulletin 17C (England et al., 2018).
Parameters:
annual_max: Annual maximum series. May contain zero / negative values
which will be treated as censored.
perception_thresholds: Optional list of (lower, upper) pairs
defining the perception interval for each observation. When
None the algorithm automatically treats observations
≤ zero_threshold as left-censored and the remainder as
exactly observed.
zero_threshold: Values ≤ this are treated as censored (default 0.0).
regional_skew: Regional / generalised skew for weighted skew.
regional_skew_mse: MSE of the regional skew estimate.
return_periods: Return periods to estimate. Defaults to standard set.
Returns:
An :class:EMAResult with LP3 quantile estimates, confidence
intervals, and censoring metadata.
Raises: ValueError: If fewer than 5 total observations.
References: England, J. F. Jr., Cohn, T. A., Faber, B. A., Stedinger, J. R., Thomas, W. O. Jr., Veilleux, A. G., Kiang, J. E., & Mason, R. R. Jr. (2018). Guidelines for determining flood flow frequency — Bulletin 17C. USGS TM 4-B5. https://doi.org/10.3133/tm4B5
Cohn, T. A., Lane, W. L., & Baier, W. G. (1997). An algorithm for
computing moments-based flood quantile estimates when historical
flood information is available. Water Resources Research, 33(9),
2089-2096. https://doi.org/10.1029/96WR03706
fit_gev ¶
fit_gev(discharge: Series, *, return_periods: list[int] | None = None, ci_level: float | None = 0.9, max_abs_shape: float = 0.5) -> FloodFreqResult
Fit a Generalized Extreme Value (GEV) distribution via MLE with L-moments seeding.
Uses L-moments parameter estimates to seed maximum likelihood estimation and constrains the shape parameter to max_abs_shape (default 0.5) to prevent unstable tail estimates on short or moderate records (n < 50). If the MLE fit produces degenerate or unplausible shape parameters, it falls back to the robust L-moments fit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Daily discharge time series or annual maxima series. |
required |
return_periods
|
list[int] | None
|
Return periods in years (default: [2, 5, 10, 25, 50, 100, 200, 500]). |
None
|
ci_level
|
float | None
|
Confidence level for bootstrap CIs (default 0.90). |
0.9
|
max_abs_shape
|
float
|
Maximum allowed absolute value for GEV shape parameter |c| (default 0.5). |
0.5
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class:`FloodFreqResult` with quantile estimates.
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If fewer than 5 annual maxima are available. |
fit_gev_lmoments ¶
fit_gev_lmoments(annual_maxima: ndarray | Series, return_periods: list[float] | None = None) -> FloodFreqResult
Fit GEV distribution using L-moments method.
More robust than MLE for small samples (n < 50). The shape parameter k is estimated from L-skewness using the Hosking (1997) approximation:
c = 2 / (3 + t3) − ln2 / ln3
k ≈ 7.8590 c + 2.9554 c²
Parameters: annual_maxima: Array of annual maximum values. return_periods: Return periods in years. Defaults to standard set.
Returns:
A :class:FloodFreqResult with fitted parameters and return levels.
Raises: ValueError: If fewer than 5 values are provided.
fit_gpd ¶
fit_gpd(exceedances: ndarray | Series, threshold: float, return_periods: list[float] | None = None, total_observations: int | None = None) -> FloodFreqResult
Fit Generalised Pareto Distribution using Peaks-Over-Threshold method.
Parameters:
exceedances: Values above the threshold (already filtered).
threshold: The threshold used for POT selection.
return_periods: Return periods in years.
total_observations: Total number of observations used to compute
exceedance rate. If None, assumed equal to len(exceedances).
Returns:
A :class:FloodFreqResult with fitted parameters and return levels.
Raises: ValueError: If fewer than 10 exceedances are provided.
fit_gumbel ¶
fit_gumbel(annual_maxima: ndarray | Series, return_periods: list[float] | None = None) -> FloodFreqResult
Fit Gumbel (Type I) extreme value distribution.
Special case of GEV with shape=0. Uses scipy.stats.gumbel_r (MLE).
Gumbel CDF: F(x) = exp(-exp(-(x - loc) / scale))
Parameters: annual_maxima: Array of annual maximum values. return_periods: Return periods in years. Defaults to standard set.
Returns:
A :class:FloodFreqResult with fitted parameters and return levels.
Raises: ValueError: If fewer than 5 values are provided.
fit_lp3 ¶
fit_lp3(discharge: Series, *, return_periods: list[int] | None = None, regional_skew: float | None = None, regional_skew_mse: float = 0.302, ci_level: float = 0.9, zero_threshold: float = 0.0) -> FloodFreqResult
Fit a Log-Pearson Type III distribution (Bulletin 17C approach).
When regional_skew is provided the station skew is adjusted using the inverse-variance weighted average described in Bulletin 17C §5.2.4 (England et al., 2018). Confidence intervals are computed via the variance-of-estimate approach (Bulletin 17C §6).
Parameters:
discharge: Daily discharge series with a DatetimeIndex.
return_periods: Return periods to estimate. Defaults to standard set.
regional_skew: Generalised / regional skew coefficient. When
None (default) the station skew is used unmodified for
backward compatibility.
regional_skew_mse: Mean-square error of the regional skew estimate.
Default 0.302 is the USGS nationwide value.
ci_level: Confidence level for return-period intervals (0 < ci < 1).
zero_threshold: Values ≤ this are excluded before fitting.
Returns:
A :class:FloodFreqResult with quantile estimates and optional CIs.
Raises: ValueError: If fewer than 5 annual maxima or all values ≤ zero_threshold.
References: England, J. F. Jr., Cohn, T. A., Faber, B. A., Stedinger, J. R., Thomas, W. O. Jr., Veilleux, A. G., Kiang, J. E., & Mason, R. R. Jr. (2018). Guidelines for determining flood flow frequency — Bulletin 17C. U.S. Geological Survey Techniques and Methods 4-B5. https://doi.org/10.3133/tm4B5
fit_nonstationary_gev ¶
fit_nonstationary_gev(annual_maxima: ndarray | Series, years: ndarray | Series, return_periods: list[float] | None = None, max_abs_shape: float | None = 0.5) -> NonStationaryGEVResult
Fit GEV with time-varying location: loc(t) = mu0 + mu1 * (t − t̄).
The trend significance is assessed via a likelihood-ratio test comparing
the non-stationary model to a stationary GEV fitted by the same
likelihood. The likelihood is written in the Coles convention (shape
xi, heavy tail for xi > 0); the result reports the shape in the
scipy convention (c = -xi) and the return levels use it as such.
Both fits start from scipy's stationary maximum-likelihood estimate (the
non-stationary one with no trend), so the non-stationary likelihood is
never worse than the stationary one and the test statistic is not negative.
max_abs_shape bounds |xi| (0.5 by default, the plausible range for
floods, Martins and Stedinger 2000), which keeps short or bootstrap samples
from running to an absurd tail; None leaves it free.
Parameters:
annual_maxima: Array of annual maximum values.
years: Corresponding year values (same length as annual_maxima).
return_periods: Return periods in years. Defaults to standard set.
max_abs_shape: Bound on the absolute Coles shape, or None.
Returns:
A :class:NonStationaryGEVResult.
Raises: ValueError: If input arrays differ in length or have fewer than 10 values.
fit_weibull_min ¶
fit_weibull_min(annual_minima: ndarray | Series, return_periods: list[float] | None = None) -> FloodFreqResult
Fit Weibull distribution to annual minima for low-flow frequency analysis.
Uses scipy.stats.weibull_min (MLE). Return periods relate to the
probability of flows below a given level.
Parameters: annual_minima: Array of annual minimum values. return_periods: Return periods in years. Defaults to standard set.
Returns:
A :class:FloodFreqResult with fitted parameters and return levels.
Raises: ValueError: If fewer than 5 values are provided.
grubbs_beck_test ¶
Multiple Grubbs-Beck (MGB) test for low-outlier detection.
Implements the iterative procedure described in Bulletin 17C Appendix 6 (Cohn et al., 2013). The test repeatedly identifies the smallest observation that is significantly low relative to the remaining sample.
Parameters: annual_max: 1-D array of annual maximum values (all positive). alpha: Significance level for the test.
Returns:
A 2-tuple (threshold, mask) where threshold is the low-outlier
cutoff (log10 scale back-transformed) and mask is a boolean array
with True for observations identified as low outliers.
References: Cohn, T. A., England, J. F. Jr., Berenbrock, C. E., Mason, R. R., Stedinger, J. R., & Lamontagne, J. R. (2013). A generalized Grubbs-Beck test statistic for detecting multiple potentially influential low outliers in flood series. Water Resources Research, 49(8), 5047-5058.
Grubbs, F. E. & Beck, G. (1972). Extension of sample sizes and
percentage points for significance tests of outlying observations.
Technometrics, 14(4), 847-854.
leave_one_out_cv ¶
leave_one_out_cv(discharge: Series, distribution: str = 'gev', return_periods: list[int] | None = None) -> dict
Leave-one-out cross-validation for flood frequency fits.
For each held-out year, the distribution is fitted on the remaining years and the held-out observation is compared against the fitted median (T = 2-year return level).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Annual maximum discharge series (with a |
required |
distribution
|
str
|
Distribution key: |
'gev'
|
return_periods
|
list[int]
|
Return periods used internally. Defaults to |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
Keys: |
lmoments_from_sample ¶
Compute L-moments (L1–L4) and L-moment ratios (t3, t4) from a sample.
L-moments are linear combinations of probability weighted moments (PWMs).
Parameters: data: 1-D array of observations.
Returns:
Dictionary with keys L1, L2, L3, L4, t3, t4.
Raises: ValueError: If fewer than 4 observations are provided.
probability_plot_correlation ¶
Probability Plot Correlation Coefficient (PPCC).
Computes the Pearson correlation between the sorted observations and the corresponding theoretical quantiles. Values close to 1 indicate a good fit.
Parameters: data: Observed sample. distribution: Distribution name. params: Distribution parameters.
Returns: PPCC value (between 0 and 1 for reasonable fits).
regional_frequency_analysis ¶
regional_frequency_analysis(sites: dict[str, ndarray], return_periods: list[float] | None = None) -> RegionalResult
L-moment based regional frequency analysis (Hosking & Wallis method).
Steps: 1. Compute L-moments for each site. 2. Discordancy test (flag sites with unusual L-moments). 3. Heterogeneity measure (H < 1 → acceptably homogeneous). 4. Fit regional growth curve using weighted regional L-moments. 5. Combine with site-specific index flood for return levels.
Parameters: sites: Mapping of site identifier → annual maxima array. return_periods: Return periods in years. Defaults to standard set.
Returns:
A :class:RegionalResult.
Raises: ValueError: If fewer than 2 sites are provided.
select_pot_threshold ¶
Select optimal threshold for Peaks-Over-Threshold analysis.
Parameters:
data: Array of observations.
method: Selection method — "mean_residual", "percentile"
(95th percentile), or "sqrt_rule" (mean + 1.5 × std).
Returns: Optimal threshold value.
Raises: ValueError: If method is not recognised.
weighted_skew ¶
weighted_skew(station_skew: float, regional_skew: float, n: int, regional_mse: float = 0.302) -> float
Compute weighted skew per Bulletin 17C §5.2.4.
Combines the station skew Gs with a generalised / regional skew
Gr using inverse-variance weights:
.. math::
G_w = w_1 G_s + w_2 G_r
where w_1 = MSE_r / (MSE_s + MSE_r) and w_2 = 1 − w_1.
Parameters:
station_skew: Station skew coefficient Gs.
regional_skew: Regional / generalised skew Gr.
n: Number of annual maximum observations.
regional_mse: Mean-square error of the regional skew estimate.
Default 0.302 is the USGS nationwide value from Bulletin 17C.
Returns:
Weighted skew coefficient Gw.
References: England, J. F. Jr. et al. (2018). Guidelines for determining flood flow frequency — Bulletin 17C. USGS TM 4-B5. https://doi.org/10.3133/tm4B5
flow_duration_curve ¶
Compute a flow duration curve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Time-series of discharge values (any DatetimeIndex). |
required |
percentiles
|
list[float] | None
|
Exceedance percentiles to extract. Defaults to
|
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class:`FDCResult` containing sorted discharges and extracted
|
|
percentile values.
|
|
low_flow_stat ¶
Compute nQm low-flow statistic (e.g. 7Q10).
The nQm is the minimum n-day rolling average that occurs with a return period of m years, estimated using the Weibull plotting position.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Daily discharge series with a DatetimeIndex. |
required |
n_day
|
int
|
Rolling window size in days. |
7
|
return_period
|
int
|
Return period in years. |
10
|
Returns:
| Type | Description |
|---|---|
The estimated nQm value in the same units as the input discharge.
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If there are fewer than 3 complete water years. |
cross_validate_rating ¶
K-fold cross-validation of a rating curve fit.
Parameters: stage: Stage measurements. discharge: Discharge measurements. k_folds: Number of folds (default 5).
Returns:
Dict with 'mean_rmse', 'std_rmse', 'mean_r2', and
'fold_results' (list of per-fold dicts).
Raises: ValueError: If inputs are invalid.
detect_rating_shift ¶
detect_rating_shift(stage: ndarray, discharge: ndarray, timestamps: ndarray | DatetimeIndex, window_size: int = 20) -> list[dict]
Detect temporal shifts in the stage-discharge relationship.
Fits rolling-window rating curves and compares the residual variance of successive windows using a chi-squared test. Significant changes are flagged as rating shifts.
Parameters: stage: Stage measurements. discharge: Corresponding discharge measurements. timestamps: Observation timestamps. window_size: Number of observations per rolling window.
Returns:
List of dicts, each containing 'timestamp', 'shift_magnitude',
and 'p_value'.
Raises: ValueError: If inputs are invalid.
export_hec_ras ¶
Export a rating curve to HEC-RAS compatible format.
Writes a simple table of stage-discharge pairs at regular intervals spanning the fitted stage range.
Parameters:
result: Fitted :class:RatingCurveResult.
filepath: Output file path.
fit_rating_curve ¶
Fit a power-law rating curve Q = a * (H - H₀)^b.
If h0 is None, it is optimised together with a and b using
:func:scipy.optimize.curve_fit.
Parameters:
stage: Water level (stage) measurements.
discharge: Corresponding discharge measurements.
h0: Optional fixed stage offset. If None, estimated from data.
Returns:
:class:RatingCurveResult with fitted parameters and diagnostics.
Raises: ValueError: If fewer than 5 stage-discharge pairs are provided, discharge contains negative values, or arrays contain NaN.
fit_segmented_rating_curve ¶
fit_segmented_rating_curve(stage: ndarray, discharge: ndarray, n_segments: int = 2, breakpoints: list[float] | None = None) -> RatingCurveResult
Fit a multi-segment rating curve with breakpoints.
Each segment is fitted independently as a power-law. If breakpoints are not provided, optimal breakpoints are found by minimising total RMSE over a grid of candidate values.
Parameters:
stage: Water level (stage) measurements.
discharge: Corresponding discharge measurements.
n_segments: Number of segments (default 2).
breakpoints: Explicit breakpoint stage values. Length must equal
n_segments - 1. If None, breakpoints are optimised.
Returns:
:class:RatingCurveResult with per-segment parameters in segments.
Raises: ValueError: If inputs are invalid or segments cannot be fitted.
predict_discharge ¶
Predict discharge from stage using a fitted rating curve.
For segmented curves the appropriate segment is selected for each stage value.
Parameters:
result: Fitted :class:RatingCurveResult.
stage: Stage values to predict at.
Returns: Predicted discharge array.
predict_stage ¶
Inverse prediction: compute stage from discharge.
Solves H = (Q / a)^(1/b) + H₀ for the primary (or first) segment.
For segmented curves the first segment whose discharge range contains the
query value is used.
Parameters:
result: Fitted :class:RatingCurveResult.
discharge: Discharge values.
Returns: Predicted stage array.
rating_curve_uncertainty ¶
rating_curve_uncertainty(result: RatingCurveResult, stage: ndarray, confidence: float = 0.95) -> tuple[np.ndarray, np.ndarray]
Compute prediction intervals for discharge estimates.
Uses a residual-based approach: the standard error of the residuals is scaled by the appropriate t-distribution quantile.
Parameters:
result: Fitted :class:RatingCurveResult.
stage: Stage values at which to compute intervals.
confidence: Confidence level (default 0.95).
Returns: Tuple of (lower_bound, upper_bound) discharge arrays.
fit_master_recession ¶
Fit a master recession curve to the identified segments.
Uses least-squares fitting of ln(Q/Q₀) vs time to estimate the recession constant k in the exponential model Q(t) = Q₀·e^(−t/k).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
segments
|
list[RecessionSegment]
|
Recession segments from :func: |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
class:`RecessionResult` with the fitted recession constant and
|
|
goodness-of-fit metrics.
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If no segments are provided. |
identify_recessions ¶
identify_recessions(discharge: Series, *, min_length: int = 5, min_decline_pct: float = 0.05) -> list[RecessionSegment]
Identify recession segments in a daily discharge series.
A recession is a continuous period where each day's discharge is less than the previous day's. Very short segments or those with negligible total decline are excluded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Daily discharge series with a DatetimeIndex. |
required |
min_length
|
int
|
Minimum segment length in days. |
5
|
min_decline_pct
|
float
|
Minimum total decline as a fraction of the starting value. |
0.05
|
Returns:
| Type | Description |
|---|---|
List of :class:`RecessionSegment` instances.
|
|
recession_analysis ¶
recession_analysis(discharge: Series, *, min_length: int = 5, min_decline_pct: float = 0.05) -> RecessionResult
Run full recession analysis: identify segments + fit MRC.
Convenience function combining :func:identify_recessions and
:func:fit_master_recession.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discharge
|
Series
|
Daily discharge series with a DatetimeIndex. |
required |
min_length
|
int
|
Minimum recession segment length in days. |
5
|
min_decline_pct
|
float
|
Minimum total decline fraction. |
0.05
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class:`RecessionResult`.
|
|
baseflow_index_simple ¶
Quick BFI using the Lyne–Hollick 1-pass digital filter.
Uses alpha=0.925 and a single forward pass for speed. For a more
robust estimate use :func:aquascope.hydrology.baseflow.lyne_hollick
directly with multiple passes.
Parameters: discharge: Daily discharge time series with DatetimeIndex.
Returns: Baseflow index (0–1).
compare_signatures ¶
Compare two signature reports field-by-field.
Parameters:
sig1: First :class:SignatureReport.
sig2: Second :class:SignatureReport.
Returns:
Dictionary of {field_name: absolute_percent_difference} for every
numeric field. Fields that are None in either report are skipped.
compute_signatures ¶
compute_signatures(discharge: Series, precipitation: Series | None = None, area_km2: float | None = None) -> SignatureReport
Compute comprehensive hydrological signatures from daily streamflow.
Parameters: discharge: Daily discharge time series (pd.Series with DatetimeIndex). Must contain at least 365 non-NaN values. precipitation: Optional daily precipitation series aligned with discharge. When provided, runoff ratio and elasticity are calculated. area_km2: Optional catchment area in km². Currently reserved for future unit-conversion but not required for any signature.
Returns:
:class:SignatureReport with all computed signatures.
Raises: ValueError: If discharge has fewer than 365 non-NaN values.
fdc_slope ¶
Slope of the flow duration curve between lower and upper exceedance percentiles.
Calculates the FDC slope in log space per Sawicz et al. (2011):
.. math:: S_{\text{FDC}} = \frac{\ln(Q_{p_1}) - \ln(Q_{p_2})}{p_2 - p_1}
where :math:p_1 (lower, default 0.33) and :math:p_2 (upper, default 0.66)
are exceedance probabilities. A steep FDC slope indicates a flashy, rain-dominated
catchment, while a flat slope indicates strong storage or groundwater contribution.
Parameters: discharge: Daily discharge time series with DatetimeIndex. lower: Lower exceedance probability (default 0.33). upper: Upper exceedance probability (default 0.66).
Returns: FDC slope (dimensionless, ≥ 0).
flashiness_index ¶
Richards-Baker Flashiness Index.
.. math:: FI = \frac{\sum |Q_i - Q_{i-1}|}{\sum Q_i}
Higher values indicate a more flashy/responsive catchment.
Parameters: discharge: Daily discharge time series with DatetimeIndex.
Returns: Flashiness index (dimensionless, ≥ 0).
flow_elasticity ¶
Sankarasubramanian precipitation-streamflow elasticity.
Computed year-by-year as:
.. math:: E = \text{median}\left(\frac{dQ / \bar{Q}}{dP / \bar{P}}\right)
where dQ and dP are annual departures from the long-term mean. An elasticity > 1 means streamflow is proportionally more variable than precipitation.
Parameters: discharge: Daily discharge time series with DatetimeIndex. precipitation: Daily precipitation with the same DatetimeIndex.
Returns: Elasticity coefficient (dimensionless).
Raises: ValueError: If fewer than 2 complete years are available.
recession_constant ¶
Mean recession constant from all recession segments.
A recession segment is a run of consecutive days where discharge
decreases. For each segment of at least min_length days the
exponential decay rate k is estimated by linear regression of
ln(Q) against time. The median k across all segments is
returned.
Parameters: discharge: Daily discharge time series with DatetimeIndex. min_length: Minimum number of consecutive falling days to qualify as a recession segment.
Returns: Median recession constant k (day⁻¹, positive).
runoff_ratio ¶
Runoff ratio (total runoff / total precipitation).
Measures the fraction of precipitation that leaves the catchment as streamflow over a shared observation period (Sawicz et al. 2011).
Parameters: discharge: Daily discharge time series with DatetimeIndex. precipitation: Daily precipitation time series with DatetimeIndex.
Returns: Runoff ratio (dimensionless, ≥ 0).
seasonality_index ¶
Markham's seasonality index and concentration month.
Monthly mean flows are treated as vectors with direction equal to the month's angular position on a unit circle. The resultant's magnitude (normalised) gives the seasonality index and its direction gives the peak month.
Parameters: discharge: Daily discharge time series with DatetimeIndex.
Returns:
Tuple of (index, peak_month) where index ranges from 0
(uniform flow throughout the year) to 1 (all flow concentrated
in a single month), and peak_month is 1–12.
similarity_score ¶
similarity_score(sig1: SignatureReport, sig2: SignatureReport, weights: dict[str, float] | None = None) -> float
Compute overall similarity between two catchments.
The score is a weighted Euclidean distance in normalised signature space. A score of 0 means the reports are identical; higher values indicate greater dissimilarity.
Parameters:
sig1: First :class:SignatureReport.
sig2: Second :class:SignatureReport.
weights: Optional mapping of field name → weight. Fields not in
the dict receive a weight of 1.0. Defaults emphasise BFI,
flashiness, seasonality, and runoff ratio.
Returns: Weighted Euclidean distance (≥ 0).
stage_to_runoff ¶
stage_to_runoff(rating: RatingCurveResult, stage: ndarray | Series, catchment_area_km2: float) -> pd.Series
Convert a stage time series to area-normalized daily runoff (mm/day).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rating
|
RatingCurveResult
|
A fitted rating curve, e.g. from :func: |
required |
stage
|
array - like or Series
|
Stage (water level) values. If a |
required |
catchment_area_km2
|
float
|
Upstream drainage area in km2. Must be positive. |
required |
Returns:
| Type | Description |
|---|---|
Series
|
Runoff in mm/day, same length and index as the input stage series. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Agricultural water management¶
FAO-56 Penman–Monteith, crop water requirements, soil water balance.
aquascope.agri ¶
Agricultural water management module.
Implements FAO-56 Penman-Monteith reference evapotranspiration, crop water requirements, and soil water balance modeling.
AgricultureBenchmarkResult
dataclass
¶
AgricultureBenchmarkResult(metric_id: str, metric_name: str, output_unit: str, summary: str, table: DataFrame)
Structured result from an AQUASTAT benchmarking workflow.
IrrigationPlan
dataclass
¶
IrrigationPlan(crop: str, planting_date: date, season_end_date: date, efficiency: float, total_eto_mm: float, total_precipitation_mm: float, total_effective_rain_mm: float, total_etc_mm: float, total_net_irrigation_mm: float, total_gross_irrigation_mm: float, total_applied_irrigation_mm: float, irrigation_trigger_days: int, schedule: DataFrame, balance: DataFrame)
Structured result from a crop irrigation planning workflow.
WaPORProductivityResult
dataclass
¶
WaPORProductivityResult(metric_id: str, metric_name: str, output_unit: str, aggregate_value: float, summary: str, table: DataFrame, aquastat_context: list[AgricultureBenchmarkResult] | None = None)
Structured result from a WaPOR productivity workflow.
SoilWaterBalance ¶
SoilWaterBalance(soil: SoilProperties, depletion_fraction: float = 0.5, initial_depletion: float = 0.0)
Daily soil water balance tracker.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
soil
|
SoilProperties
|
Soil hydraulic properties. |
required |
depletion_fraction
|
float
|
Fraction of TAW that can be depleted before stress (p, default 0.5). |
0.5
|
initial_depletion
|
float
|
Starting depletion in mm (default 0.0 = field capacity). |
0.0
|
References
Allen et al. (1998), FAO-56 Ch. 8. ISBN 92-5-104219-5.
step ¶
step(etc: float, precipitation: float = 0.0, irrigation: float = 0.0, runoff: float = 0.0) -> SoilWaterStatus
Advance the water balance by one day.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
etc
|
float
|
Crop evapotranspiration (mm/day). |
required |
precipitation
|
float
|
Daily precipitation (mm). |
0.0
|
irrigation
|
float
|
Applied irrigation (mm). |
0.0
|
runoff
|
float
|
Surface runoff (mm). |
0.0
|
Returns:
| Type | Description |
|---|---|
SoilWaterStatus
|
Updated soil water status. |
run ¶
run(etc_series: Series, precip_series: Series, irrigation_series: Series | None = None) -> pd.DataFrame
Run the water balance over a time series.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
etc_series
|
Series
|
Daily ETc (mm/day) with |
required |
precip_series
|
Series
|
Daily precipitation (mm) with |
required |
irrigation_series
|
Series | None
|
Daily irrigation (mm). If None, no irrigation is applied. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Daily soil water status records. |
auto_irrigate ¶
Run balance with automatic irrigation when depletion exceeds RAW.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
etc_series
|
Series
|
Daily ETc (mm/day). |
required |
precip_series
|
Series
|
Daily precipitation (mm). |
required |
efficiency
|
float
|
Irrigation system efficiency (0-1). |
0.7
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Daily water balance with |
Notes
irrigation_mm reports the gross water applied (water pumped),
accounting for conveyance/application efficiency. Only the net
depth - the amount that actually reaches the root zone, i.e. the
depletion being refilled - is passed into :meth:step, so
conveyance/application losses are not double-counted as
deep_percolation_mm.
benchmark_aquastat ¶
benchmark_aquastat(df: DataFrame, metric_id: str, *, year: int | None = None, countries: list[str] | None = None, latest_only: bool = True, top_n: int | None = None) -> AgricultureBenchmarkResult
Compute a country-scale benchmark from AQUASTAT data.
list_benchmark_metrics ¶
Return supported benchmark metric IDs.
crop_water_requirement ¶
crop_water_requirement(eto_series: Series, crop: str, planting_date: date, stage_lengths: dict[str, int] | None = None, method: str = 'single', kc_max: float = 1.2, few: float = 1.0, kr: float = 1.0, *, ground_cover: float | None = None, density: str | None = None, variety: str | None = None, class_name: str | None = None) -> pd.DataFrame
Compute daily crop water requirement over the growing season.
Supports both the FAO-56 single crop coefficient (Kc) and dual crop coefficient (Kcb + Ke) approaches, with optional woody-crop parameterization per FAO-56 Rev.1 (2025).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
eto_series
|
Series
|
Daily reference ET (mm/day) with a |
required |
crop
|
str
|
Crop name (key in |
required |
planting_date
|
date
|
Planting or sowing date. |
required |
stage_lengths
|
dict[str, int] | None
|
Days per stage. Defaults to |
None
|
method
|
str
|
|
'single'
|
kc_max
|
float
|
Maximum Kc after rain/irrigation (dual method only, default 1.20).
See |
1.2
|
few
|
float
|
Exposed-and-wetted soil fraction (dual method only, default 1.0).
See |
1.0
|
kr
|
float
|
Soil evaporation reduction coefficient (dual method only, default 1.0).
See |
1.0
|
ground_cover
|
float | None
|
Effective ground cover fraction (0–1), passed to |
None
|
density
|
str | None
|
Planting density or training class, passed to |
None
|
variety
|
str | None
|
Crop variety or sub-species, passed to |
None
|
class_name
|
str | None
|
Explicit class name, passed to |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Single method columns: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If method is not |
References
Allen et al. (1998); Pereira et al. (2025), FAO-56 Ch. 6 (single), Ch. 7 (dual).
get_kc ¶
get_kc(crop: str, stage: str | None = None, *, ground_cover: float | None = None, density: str | None = None, variety: str | None = None, class_name: str | None = None) -> float | dict[str, float]
Get single crop coefficient(s) for a crop from FAO-56 Table 12 / Rev.1 Tables 6.1–6.3.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
crop
|
str
|
Crop name (must be a key in |
required |
stage
|
str | None
|
Growth stage: |
None
|
ground_cover
|
float | None
|
Effective ground cover fraction (0–1), used to resolve woody-crop classes (e.g. olive, grape, citrus) per FAO-56 Rev.1 Table 6.3. |
None
|
density
|
str | None
|
Planting density or training class (e.g. |
None
|
variety
|
str | None
|
Crop variety or sub-species (e.g. |
None
|
class_name
|
str | None
|
Explicit FAO-56 Rev.1 class identifier from |
None
|
Returns:
| Type | Description |
|---|---|
float | dict[str, float]
|
Kc value for the given stage, or a dict of all stages. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If crop, stage, class_name, variety, or density is unknown. |
References
Allen et al. (1998), Table 12; Pereira et al. (2025), FAO-56 Rev.1 Tables 6.1–6.3.
irrigation_schedule ¶
irrigation_schedule(eto_series: Series, precip_series: Series, crop: str, planting_date: date, efficiency: float = 0.7, stage_lengths: dict[str, int] | None = None, method: str = 'single', kc_max: float = 1.2, few: float = 1.0, kr: float = 1.0, *, ground_cover: float | None = None, density: str | None = None, variety: str | None = None, class_name: str | None = None) -> pd.DataFrame
Full irrigation scheduling over the growing season.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
eto_series
|
Series
|
Daily reference ET (mm/day) with a |
required |
precip_series
|
Series
|
Daily precipitation (mm) with a |
required |
crop
|
str
|
Crop name. |
required |
planting_date
|
date
|
Planting date. |
required |
efficiency
|
float
|
Irrigation system efficiency (0–1). |
0.7
|
stage_lengths
|
dict[str, int] | None
|
Days per stage. |
None
|
method
|
str
|
|
'single'
|
kc_max
|
float
|
Maximum Kc after rain/irrigation (dual method only, default 1.20). |
1.2
|
few
|
float
|
Exposed-and-wetted soil fraction (dual method only, default 1.0). |
1.0
|
kr
|
float
|
Soil evaporation reduction coefficient (dual method only, default 1.0). |
1.0
|
ground_cover
|
float | None
|
Passed to |
None
|
density
|
str | None
|
Passed to |
None
|
variety
|
str | None
|
Passed to |
None
|
class_name
|
str | None
|
Passed to |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
All columns from |
References
Allen et al. (1998); Pereira et al. (2025), FAO-56 Ch. 7.
hargreaves ¶
Hargreaves reference ET₀ estimate (temperature-based).
A simpler alternative when only temperature data is available::
ET₀ = 0.0023 × (T_mean + 17.8) × (T_max − T_min)^0.5 × Ra
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t_min
|
float
|
Minimum daily temperature (°C). |
required |
t_max
|
float
|
Maximum daily temperature (°C). |
required |
ra
|
float
|
Extraterrestrial radiation (MJ/m²/day). Use |
required |
Returns:
| Type | Description |
|---|---|
float
|
Reference evapotranspiration ET₀ in mm/day. |
References
Hargreaves, G. H. & Samani, Z. A. (1985). Reference crop evapotranspiration from temperature. Applied Engineering in Agriculture, 1(2), 96–99.
penman_monteith_daily ¶
penman_monteith_daily(t_min: float, t_max: float, rh_min: float, rh_max: float, u2: float, rs: float, latitude: float, elevation: float, doy: int) -> float
FAO-56 Penman-Monteith daily reference evapotranspiration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t_min
|
float
|
Minimum daily temperature (°C). |
required |
t_max
|
float
|
Maximum daily temperature (°C). |
required |
rh_min
|
float
|
Minimum relative humidity (%). |
required |
rh_max
|
float
|
Maximum relative humidity (%). |
required |
u2
|
float
|
Wind speed at 2 m height (m/s). |
required |
rs
|
float
|
Incoming solar radiation (MJ/m²/day). |
required |
latitude
|
float
|
Latitude in decimal degrees. |
required |
elevation
|
float
|
Station elevation above sea level (m). |
required |
doy
|
int
|
Day of the year (1–366). |
required |
Returns:
| Type | Description |
|---|---|
float
|
Reference evapotranspiration ET₀ in mm/day. |
References
Allen et al. (1998), Eq. 6. ISBN 92-5-104219-5.
penman_monteith_series ¶
Apply Penman-Monteith ET₀ to each row of a weather DataFrame.
The DataFrame must have a DatetimeIndex and the following columns:
t_min, t_max, rh_min, rh_max, wind_speed,
solar_radiation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
Daily weather observations. |
required |
latitude
|
float
|
Latitude in decimal degrees. |
required |
elevation
|
float
|
Station elevation in metres. |
required |
Returns:
| Type | Description |
|---|---|
Series
|
Daily ET₀ values in mm/day, indexed like df. |
References
Allen et al. (1998), FAO Irrigation and Drainage Paper 56. ISBN 92-5-104219-5.
default_season_end_date ¶
default_season_end_date(crop: str, planting_date: date, stage_lengths: dict[str, int] | None = None) -> date
Return the default end date for a crop season.
fetch_openmeteo_plan_inputs ¶
fetch_openmeteo_plan_inputs(latitude: float, longitude: float, start_date: str, end_date: str) -> tuple[pd.Series, pd.Series]
Fetch daily ET0 and precipitation from Open-Meteo for planning.
plan_irrigation ¶
plan_irrigation(crop: str, planting_date: date, eto_series: Series, precip_series: Series, soil: SoilProperties, *, efficiency: float = 0.7, depletion_fraction: float = 0.5, initial_depletion: float = 0.0, stage_lengths: dict[str, int] | None = None) -> IrrigationPlan
Build a full irrigation plan from daily ET and precipitation series.
estimate_wapor_productivity ¶
estimate_wapor_productivity(*, metric_id: str, aeti_df: DataFrame | None = None, npp_df: DataFrame | None = None, ret_df: DataFrame | None = None, aquastat_df: DataFrame | None = None, aquastat_metrics: list[str] | None = None, aquastat_year: int | None = None, aquastat_countries: list[str] | None = None, aquastat_top_n: int | None = 10) -> WaPORProductivityResult
Compute a WaPOR productivity or ET performance metric.
list_productivity_metrics ¶
Return supported productivity metric IDs.
Visualization¶
aquascope.viz ¶
AquaScope visualisation module.
Provides publication-quality plots for water-quality analysis, hydrology,
forecasting, and spatial data. All functions lazily import matplotlib
so the module can be imported even when the viz optional dependency
group is not installed — an ImportError is raised only when a plot
function is actually called.
Quick start::
from aquascope.viz import plot_timeseries, plot_forecast, plot_fdc
plot_timeseries(df, title="Daily Discharge")
plot_forecast(observed=train, forecast=pred, save_path="forecast.png")
plot_fdc(discharge_series, save_path="fdc.svg")