Skip to main content

HydroSeason

Tests Docs Python License: MIT DOI

HydroSeason is an open-source Python package for hydrological-year detection and seasonal/aseasonal analysis from monthly satellite-derived surface-water extent.

HydroSeason turns a monthly surface-water record into a hydrological year report — from a satellite-derived water-mask time series (such as Digital Earth Australia Water Observations), it works out when a catchment floods and dries, where each hydrological year begins and ends, and whether the pattern is even seasonal at all.

[!NOTE] HydroSeason analyzes surface-water extent percentages. It does not estimate river discharge, channel depth, total water volume, or groundwater storage.


What you get

HydroSeason report preview

One function call gives you one self-contained HTML report, an interactive water-extent timeline with each hydrological year, its wet and dry phases, and the flood events and low spells found in the record. Plus four CSVs carrying the same numbers for your own analysis: _monthly, _hydro_years, _wet_event, and _low_spells.

Open a real one (no install needed):


Installation

pip install hydroseason              # Core: CSV detection & reports (pandas, numpy)
pip install "hydroseason[raster]"    # + xarray, rioxarray, rasterio, geopandas, dask, zarr
pip install "hydroseason[stac]"      # + pystac-client, odc-stac (DEA STAC acquisition)
pip install "hydroseason[all]"       # Complete raster + STAC dependencies

Quickstart

from hydroseason import run_hydroseason

result = run_hydroseason(
    "monthly_extent.csv",
    output_dir="output/report",
    aoi_name="My AOI",
)

print(f"Regime: {result.analysis.regime.regime}")
print(f"Route: {result.analysis.route}")
print(f"HTML: {result.artifacts.html}")

run_hydroseason is the one function most people need — see the four ways to run it below for rasters, DEA fetching, and optional rainfall context.

Many AOIs: one vector row, one report

For independent DEA/STAC analyses from a multi-row vector layer, use run_hydroseason_many. One input row produces one analysis and one report; each result is isolated under its resolved identifier. This differs from run_hydroseason, which treats a multi-row AOI as one combined analysis over its union footprint. A one-row MultiPolygon is still one AOI.

from hydroseason import run_hydroseason_many

batch = run_hydroseason_many(
    "catchments.gpkg",
    output_dir="results",
    cache_dir="cache",
    start_date="2000-01-01",
    end_date="2025-12-01",
    id_col="catchment_id",
    workers="auto",
)
for outcome in batch.outcomes:
    if outcome.succeeded:
        print(outcome.id, outcome.result.artifacts.html)
    else:
        print(outcome.id, outcome.error_type, outcome.error_message)
batch.raise_for_failures()

workers="auto" uses a default concurrency cap of 2 and admits work only within 80% of currently available RAM. See the Usage Guide for memory and scheduling details.

For runs long enough to outlive a notebook session, use the CLI — same orchestrator, its own process, resumable via --cache-dir:

hydroseason run --aoi data/fitzroy_kimberley_aoi.geojson --aoi-name "Fitzroy River (WA)" \
  --start-date 2005-01-01 --end-date 2025-12-01 \
  --output-dir output/fitzroy --cache-dir cache/fitzroy

hydroseason doctor reports whether an environment has the optional dependencies a given path needs. Full recipes: CLI Recipes.


How it works

  1. You give it monthly water-extent data — a CSV you already have, a raster/NetCDF/Zarr cube, or nothing at all (it fetches Digital Earth Australia satellite data for you).
  2. It checks whether the catchment has a reliable annual cycle — a signal-to-noise ratio (SNR): how strong and repeatable the yearly wet/dry swing is compared to noise.
  3. It picks the matching analysis automatically — a strong, repeatable cycle gets per-year hydrological boundaries; an irregular or dryland catchment gets discrete flood-event and dry-spell characterization instead, rather than forcing a yearly pattern that isn't really there.
  4. Optional rainfall adds context, never changes the answer — rainfall can be fetched or supplied alongside the water data, but it only annotates the report; it can never alter the regime, route, boundaries, phases, events, or spells that were already decided from water alone.
  5. It writes one self-contained HTML report and four CSVs — open the HTML anywhere, no server needed; the CSVs are ready for your own analysis.
CSV, raster, or DEA fetch  →  run_hydroseason  →  seasonal or aseasonal route  →  HTML report + 4 CSVs

The four ways to run it

You have... Pass it as water_source Extra required
A monthly extent CSV or pandas.DataFrame the CSV path or the DataFrame none (core install)
A NetCDF/Zarr file, or an xarray object the file path, or the Dataset/DataArray hydroseason[raster]
Nothing yet — fetch it from DEA None, plus aoi=, start_date=, end_date= hydroseason[stac]
Any of the above, plus rainfall context add fetch_rainfall=True or rainfall_csv_path= hydroseason[raster] for SILO fetch

Runnable examples for each: Usage Guide — The four ways to run it, or the notebooks — start with 01_quickstart.ipynb. Acquisition internals (the fixed historical water mask, planning footprints, cache integrity, composite bundles) are documented in Advanced: DEA acquisition internals.


Case Studies

Three fully reproducible offline case studies using 2005–2025 DEA 30 m whole-catchment extent data across five Australian catchments (Daly, Fitzroy, Gilbert, Lachlan, Moonie):

  1. Main Catchment Workflow — Route-aware analysis across five catchments: three seasonal/marginal monsoonal basins, two aseasonal dryland basins.
  2. Resolution and Acquisition Evidence — Why 30 m resolution is the release standard: 60/90/300 m coarsening fails pre-declared fidelity gates for low-SNR catchments.
  3. Rainfall Context — Proves rainfall is strictly additive: every water-only column stays byte-identical with rainfall attached.

Scientific Limitations

  • Timing evidence: Fewer than 30 usable annual timings (not 30 months) can make bootstrap intervals wide; fewer than five usable annual timings is insufficient for regime assessment.

  • Circular timing: A low mean resultant length can mean diffuse timing or two cancelling preferred seasons; inspect the accompanying Kuiper uniformity result and trough evidence.

  • Extent is not Volume or Discharge: Surface area percentage (extent_pct) dilutes narrow river channels and misses sub-canopy water.

  • Cloud Gaps: High cloud/shadow invalid coverage (invalid_pct) distorts extent statistics if unflagged.

  • Resolution: Coarsening spatial resolution distorts peak/trough timing and event boundaries. 30 m resolution remains authoritative.


Entry Points

Symbol Purpose
run_hydroseason One-call orchestrator: resolve water input, analyze, optional rainfall, write report
HydroSeasonRunResult Everything a run_hydroseason call produced (.analysis, .artifacts, .rainfall_status, ...)
run_hydroseason_many DEA/STAC batch orchestrator: preserve each input vector row as one independent run
HydroSeasonBatchResult Source-ordered successful and failed per-row outcomes; call .raise_for_failures() after inspection
load_extent_csv Read a monthly extent CSV directly, for the lower-level building blocks
analyze_catchment Assess regime, then run the analysis that regime supports (the routing authority)
generate_catchment_report Write the self-contained HTML report plus the 4-CSV bundle
load_wofs_monthly_extent Fetch DEA WOfS directly, without the full orchestrator

Full API reference, grouped by task: Workflow, Loading Data, Analysis, Reporting.


Citation

If you use HydroSeason in your research, please cite the software release (see CITATION.cff):

@software{tayer_hydroseason,
  author  = {Tayer, Thiaggo C.},
  title   = {HydroSeason: Remote-sensing-first hydrological year and season detection},
  year    = {2026},
  url     = {https://github.com/tayerthiaggo/hydroseason},
  doi     = {10.5281/zenodo.21866898}
}

Full citation guidance, including the version-specific DOI policy, is in docs/citation.md.


License

MIT License — see LICENSE.

Release files for hydroseason 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hydroseason 0.1.1
File Size Uploaded
hydroseason-0.1.1.tar.gz 676.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hydroseason 0.1.1
File Interpreter ABI Platform
hydroseason-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 1.4 MB

Release files / hydroseason-0.1.1.tar.gz

Download URL hydroseason-0.1.1.tar.gz
Size 676.8 kB
Tags Source
SHA-256 checksum
How to use checksums
98da39a74e406f8938db607e9adf975f3debfdf93902aa5a6d2fef36fd6b556a
BLAKE2b-256 checksum
How to use checksums
ea06964cc820bc78669c73ad9b259003662d2b65a401fc08dafa8fe6863cd236
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

Release files / hydroseason-0.1.1-py3-none-any.whl

Download URL hydroseason-0.1.1-py3-none-any.whl
Size 698.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
139bb34658aabdf1d7e3bccc403ca9f7b6a135665baae64cdfd7156079ce5c8e
BLAKE2b-256 checksum
How to use checksums
dab18d0af80724d333a1737c6f98993aac53054f6879dd9776659b4d85040135
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page