Run an event-driven state machine on flow data
run_state_machine.RdApplies a state machine to a univariate flow time series to detect regime changes (e.g. baseflow, rising limb, peak, recession) based on estimated signal derivatives. Only state transitions are returned.
Usage
run_state_machine(
time,
flow,
params,
kernel_l = 60,
time_units = "mins",
derivative_units = "per_minute"
)Arguments
- time
A vector of timestamps (POSIXct or convertible), representing the time of each observation.
- flow
Numeric vector of flow (or discharge) values. Must be the same length as `time`.
- params
A list of parameters controlling state transitions. Passed to
update_state_no_forecast().- kernel_l
Numeric. Length scale of the smoothing kernel used in state estimation. Default is `60`.
- time_units
Character string specifying the time units of the input series (e.g. `"mins"`, `"hours"`). Passed to
estimate_state().- derivative_units
Character string specifying the units of the estimated derivatives (e.g. `"per_minute"`). Passed to
estimate_state().
Value
A data frame containing only state transitions with columns:
`time`: timestamp at which a state change occurs
`state`: the new state entered at that time
Details
The function first estimates a smoothed version of the flow signal and its
first and second derivatives using estimate_state().
A baseline flow (`baseflow_Q`) is computed as the median of the input flow series. This is used as a reference level in state transitions.
The state machine is initialised in the `"BASEFLOW"` state and updated
sequentially using update_state_no_forecast(), which determines
the next state based on:
current flow (`Q`)
first derivative (`dQ`)
second derivative (`ddQ`)
baseline flow (`baseflow_Q`)
user-defined parameters (`params`)
Only points where the state changes are recorded, resulting in a compact representation of regime transitions rather than a full time series.
Examples
# Simulated example
if (FALSE) { # \dontrun{
set.seed(1)
time <- seq.POSIXt(Sys.time(), by = "min", length.out = 200)
flow <- cumsum(rnorm(200))
params <- list(
rise_threshold = 0.1,
fall_threshold = -0.1
)
transitions <- run_state_machine(
time = time,
flow = flow,
params = params
)
head(transitions)
} # }