setpoint_events
setpoint_events ¤
SetpointChangeEvents ¤
SetpointChangeEvents(
dataframe: DataFrame,
setpoint_uuid: str,
*,
event_uuid: str = "eng:setpoint_change",
value_column: str = "value_double",
time_column: str = "systime"
)
Bases: Base
Detect step/ramp changes on a setpoint signal and compute follow-up KPIs like time-to-settle and overshoot based on an actual (process) value.
Schema assumptions (columns): - uuid, sequence_number, systime, plctime, is_delta - value_integer, value_string, value_double, value_bool, value_bytes
Example
import pandas as pd from ts_shape import SetpointChangeEvents df = pd.DataFrame({ ... "systime": pd.date_range("2025-01-01 08:00", periods=4, freq="10min"), ... "uuid": "oven:setpoint", ... "value_double": [50.0, 50.0, 60.0, 60.0], ... }) steps = SetpointChangeEvents(df, "oven:setpoint").detect_setpoint_steps(min_delta=5.0) steps[["start", "prev_level", "new_level", "magnitude"]] start prev_level new_level magnitude 0 2025-01-01 08:20:00 50.0 60.0 10.0
detect_setpoint_steps ¤
detect_setpoint_steps(
min_delta: float,
min_hold: str = "0s",
filter_noise: bool = False,
noise_threshold: float = 0.01,
) -> pd.DataFrame
Point events at times where the setpoint changes by >= min_delta and the
new level holds for at least min_hold (no subsequent change within that time).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_delta
|
float
|
Minimum magnitude of change to detect |
required |
min_hold
|
str
|
Minimum duration the new level must hold |
'0s'
|
filter_noise
|
bool
|
If True, filter out changes smaller than noise_threshold |
False
|
noise_threshold
|
float
|
Threshold for noise filtering (absolute value) |
0.01
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end (== start), duration_seconds |
DataFrame
|
(0.0), uuid, source_uuid, is_delta, change_type='step', magnitude, |
DataFrame
|
prev_level, new_level. |
detect_setpoint_ramps ¤
detect_setpoint_ramps(
min_rate: float, min_duration: str = "0s"
) -> pd.DataFrame
Interval events where |dS/dt| >= min_rate for at least min_duration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_rate
|
float
|
Minimum absolute setpoint rate of change, in setpoint units per second, for a sample-to-sample step to count as ramping. |
required |
min_duration
|
str
|
Minimum time from the first to the last ramping sample of
a contiguous run (pandas offset string). Default |
'0s'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end, duration_seconds, uuid, |
DataFrame
|
source_uuid, is_delta, change_type='ramp', avg_rate, delta. |
detect_setpoint_changes ¤
detect_setpoint_changes(
*,
min_delta: float = 0.0,
min_rate: float | None = None,
min_hold: str = "0s",
min_duration: str = "0s"
) -> pd.DataFrame
Unified setpoint change table (steps + ramps) with standardized columns.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_delta
|
float
|
Minimum step magnitude, passed to
:meth: |
0.0
|
min_rate
|
float | None
|
Minimum ramp rate in setpoint units per second, passed to
:meth: |
None
|
min_hold
|
str
|
Minimum time a new step level must hold, passed to
:meth: |
'0s'
|
min_duration
|
str
|
Minimum ramp duration, passed to
:meth: |
'0s'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end, duration_seconds, uuid, |
DataFrame
|
source_uuid, is_delta, change_type, magnitude, prev_level, |
DataFrame
|
new_level, avg_rate, delta. |
time_to_settle ¤
time_to_settle(
actual_uuid: str,
*,
tol: float = 0.0,
settle_pct: float | None = None,
hold: str = "0s",
lookahead: str = "10min"
) -> pd.DataFrame
For each setpoint change (any change), compute the settling time: the
time after which the actual signal enters the ±tolerance band around
the new setpoint and stays inside it until the end of the evaluation
window (Ogata, Modern Control Engineering, settling time t_s).
The first entry into the band is not the settling time: an
underdamped response crosses the band on every swing long before it
settles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
actual_uuid
|
str
|
UUID of the actual/process value signal |
required |
tol
|
float
|
Absolute tolerance, used when |
0.0
|
settle_pct
|
float | None
|
Tolerance as a fraction of the step magnitude (e.g.
0.02 for 2%). When given it wins over |
None
|
hold
|
str
|
Minimum duration the final inside-band run must last
before the window ends for the settle to count as confirmed
( |
'0s'
|
lookahead
|
str
|
Evaluation window after each change. It also ends at the next (later) setpoint change, after which the process follows a different setpoint. The response must be inside the band at the window's last sample to have settled. |
'10min'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end (start + the lookahead window), |
DataFrame
|
duration_seconds, uuid, source_uuid (" |
DataFrame
|
is_delta, t_settle_seconds (seconds from the change to the start |
DataFrame
|
of the final inside-band run; |
DataFrame
|
outside the band at the end of the window), settled_within_window |
DataFrame
|
(True when the response is inside the band at the end of the |
DataFrame
|
window, so a settling time exists) and settled |
DataFrame
|
(settled_within_window and the final inside-band run lasts at |
DataFrame
|
least |
overshoot_metrics ¤
overshoot_metrics(
actual_uuid: str, *, window: str = "10min"
) -> pd.DataFrame
For each change, compute peak overshoot, undershoot, and oscillation metrics relative to the new setpoint within a lookahead window.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
actual_uuid
|
str
|
UUID of the actual (process value) signal. |
required |
window
|
str
|
Lookahead window after each setpoint change in which the peak, undershoot and oscillations are measured (pandas offset string). |
'10min'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end (start + the lookahead window), |
DataFrame
|
duration_seconds, uuid, source_uuid (" |
DataFrame
|
is_delta, overshoot_abs, overshoot_pct, overshoot_ratio, |
DataFrame
|
t_peak_seconds, undershoot_abs, undershoot_pct, undershoot_ratio, |
DataFrame
|
t_undershoot_seconds, oscillation_count, oscillation_amplitude. |
DataFrame
|
|
DataFrame
|
magnitude (0-100+, Ogata's maximum percent overshoot |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
the new setpoint after it is first reached, in the same two units. |
time_to_settle_derivative ¤
time_to_settle_derivative(
actual_uuid: str,
*,
rate_threshold: float = 0.01,
lookahead: str = "10min",
hold: str = "0s"
) -> pd.DataFrame
Detect settling based on rate of change (derivative) falling below threshold. More sensitive to when the process has truly stopped moving.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
actual_uuid
|
str
|
UUID of the actual/process value signal |
required |
rate_threshold
|
float
|
Maximum absolute rate of change to consider settled |
0.01
|
lookahead
|
str
|
Maximum time window to search for settling |
'10min'
|
hold
|
str
|
Minimum duration the rate must stay below threshold |
'0s'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end (start + the lookahead window), |
DataFrame
|
duration_seconds, uuid, source_uuid (" |
DataFrame
|
is_delta, t_settle_seconds, settled, final_rate. |
rise_time ¤
rise_time(
actual_uuid: str,
*,
start_pct: float = 0.1,
end_pct: float = 0.9,
lookahead: str = "10min"
) -> pd.DataFrame
Compute rise time: time for actual to go from start_pct to end_pct of the setpoint change. Typically measured from 10% to 90% of the final value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
actual_uuid
|
str
|
UUID of the actual/process value signal |
required |
start_pct
|
float
|
Starting percentage of change (e.g., 0.1 for 10%) |
0.1
|
end_pct
|
float
|
Ending percentage of change (e.g., 0.9 for 90%) |
0.9
|
lookahead
|
str
|
Maximum time window to search |
'10min'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end (start + the lookahead window), |
DataFrame
|
duration_seconds, uuid, source_uuid (" |
DataFrame
|
is_delta, rise_time_seconds, reached_end. |
decay_rate ¤
decay_rate(
actual_uuid: str,
*,
lookahead: str = "10min",
min_points: int = 5
) -> pd.DataFrame
Estimate exponential decay rate of the settling behavior. Fits error(t) = A * exp(-lambda * t) and returns lambda.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
actual_uuid
|
str
|
UUID of the actual/process value signal |
required |
lookahead
|
str
|
Time window for analysis |
'10min'
|
min_points
|
int
|
Minimum number of points required for fitting |
5
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end (start + the lookahead window), |
DataFrame
|
duration_seconds, uuid, source_uuid (" |
DataFrame
|
is_delta, decay_rate_lambda, fit_quality_r2. |
oscillation_frequency ¤
oscillation_frequency(
actual_uuid: str,
*,
window: str = "10min",
min_oscillations: int = 2
) -> pd.DataFrame
Estimate the frequency of oscillations during settling. Counts zero crossings and estimates period.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
actual_uuid
|
str
|
UUID of the actual/process value signal |
required |
window
|
str
|
Time window for analysis |
'10min'
|
min_oscillations
|
int
|
Minimum number of oscillations to compute frequency |
2
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end (start + the lookahead window), |
DataFrame
|
duration_seconds, uuid, source_uuid (" |
DataFrame
|
is_delta, oscillation_freq_hz, period_seconds. |
control_quality_metrics ¤
control_quality_metrics(
actual_uuid: str,
*,
tol: float = 0.0,
settle_pct: float | None = None,
hold: str = "0s",
lookahead: str = "10min",
rate_threshold: float = 0.01
) -> pd.DataFrame
Comprehensive control quality metrics combining multiple performance indicators.
Computes all available metrics for each setpoint change and returns them in a single DataFrame. This includes: settling time, rise time, overshoot, undershoot, oscillations, and decay characteristics. The change table and the response windows are gathered once and shared by all of them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
actual_uuid
|
str
|
UUID of the actual/process value signal |
required |
tol
|
float
|
Absolute tolerance for settling, used when |
0.0
|
settle_pct
|
float | None
|
Settling tolerance as a fraction of the step
magnitude. When given it wins over |
None
|
hold
|
str
|
Minimum duration to confirm settling |
'0s'
|
lookahead
|
str
|
Time window for all analyses |
'10min'
|
rate_threshold
|
float
|
Rate threshold for derivative-based settling |
0.01
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with comprehensive metrics including: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|