Python API
The Python API is secondary to the command-line guides. Install hydropattern
in your own Python environment using the
API installation instructions.
These examples use the v0.3.0 API.
Results can contain NaN or pd.NA when a verdict cannot be determined;
missing input flow values are rejected. See
unknown outcomes for propagation and
reporting semantics.
Evaluate one scenario
This example selects the flow column and evaluates magnitude followed by
un-nested frequency. It uses the ordered characteristic form to retain
explicit evaluation order.
import pandas as pd
from hydropattern.parsers import build_components, parse_request
from hydropattern.patterns import evaluate_component
source = [0, 1, 0, 0, 1, 0, 0, 0, 0, 0]
data = pd.DataFrame(
{"flow": source, "dowy": range(1, len(source) + 1)},
index=pd.date_range("2020-01-01", periods=len(source), name="time"),
)
request = parse_request(
{"pulse": {"characteristics": [
{"type": "magnitude", "parameters": [">", 0]},
{"type": "frequency", "parameters": [">=", 1, 5]},
]}}
)
result = evaluate_component(data, build_components(request)[0])
print(result.df["frequency_ge1in5(union)"].tolist())
# [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0]
# Columns: flow, dowy, magnitude_gt0, frequency_ge1in5(union), pulse
Frequency counts qualifying timesteps, not distinct component events. Its successful windows mark timesteps even where the preceding magnitude condition is not met. See the frequency reference.
evaluate_component(..., data_column=0) selects one zero-based data-column
position. The final dowy column cannot be selected. The result retains the
selected scenario's name; see
result-column details.
The result dataframe preserves the input index (a datetime index is named
time) and contains, in order, the selected flow column, dowy, each
characteristic diagnostic, and the final component column. Input validation
errors, invalid column positions, and duplicate output column names are
reported as errors rather than silently selecting a different column.
Statistics for component events
Result reports numbers of component events and descriptive rates for final
component outcomes. Use bounds methods when unknown outcomes may leave more
than one possible count or rate:
count_bounds = result.event_count_bounds()
rate_bounds = result.event_rate_bounds()
print(count_bounds.lower, count_bounds.upper)
print(rate_bounds.lower, rate_bounds.upper)
Both bounds objects have named lower and upper fields. The scalar methods
result.event_count() and result.event_rate() raise ValueError when their
bounds differ; use the matching bounds method instead. The
event_count_bounds_by_water_year() and
event_rate_bounds_by_water_year() methods return mappings keyed by ending-year
water-year labels. A run crossing a water-year boundary is assigned to the
water year containing its first successful observation.
Rates use all observed intervals, including partial water years, and require
supported daily or monthly timestamps. If you construct Result directly,
provide its first_day_of_water_year metadata or ensure its timestamps and
dowy column establish one consistent boundary. Bounds treat unknown final
outcomes independently and may therefore be wider than the possibilities
allowed by dependencies in the original evaluation; they are not exact
source-dependency bounds.
Plot a scenario grid
ScenarioResults.plot_response_surface uses the same default 90% coverage
cutoff as the CLI. Override it with a fraction from 0 to 1:
scenarios.plot_response_surface(
"sustained_flow",
output_path="results",
minimum_coverage=0.75,
)
With an output directory, the method writes the eligible summary grid, a
companion coverage CSV, and a PNG. Scenarios below the cutoff or without a
defined summary remain gaps; fillin=True cannot be combined with withheld
scenarios. If fewer than three non-collinear scenarios remain, plotting raises
PLOT_NO_RENDERABLE_SURFACE after writing the grid and coverage data.
Read structured errors
Parser and plot errors expose a HydropatternError with a code, message,
context, and source:
from hydropattern.errors import HydropatternError
from hydropattern.parsers import timing_parser
try:
timing_parser([0, 100], order=1)
except HydropatternError as exc:
print(exc.envelope.code) # PARSER_INVALID_VALUE
print(exc.envelope.message)
print(exc.envelope.context)
print(exc.envelope.source) # parser
The CLI reference lists existing error codes. Review migration guidance before updating Python calls.