Monitor — Grid Modal Stream¶
A causal, real-time streaming monitor that carries the certified grid modal-growth detector online — the step from an offline benchmark to an operational early warning.
What it is for¶
The offline head-to-head certifies the detector on fixed pre-onset segments. This monitor
runs the same detector causally on a live stream: it keeps a sliding window of the most
recent per-bus voltage samples and, every step, re-scores that window with the identical
primitives the detector uses, so the streaming score on a window is bit-for-bit the offline
modal_growth_score on that same window. That identity is what makes the offline-calibrated
threshold valid online — the monitor never recalibrates.
Contract¶
GridModalStreamMonitor— pushes one per-bus sample at a time (update) and raises aStreamAlarmwhen the live growth rate crosses the certified threshold, after an optional persistence debounce, latching until the growth falls back below so each instability episode raises one lead event.StreamAlarm— a lead event: the sample index and time it fired, the growth rateσ, the threshold crossed, and the most unstable bus.GridModalStreamMonitor.from_evidence— builds the monitor straight from a sealed head-to-head artefact (aggregation, recency weighting, and matched-false-alarm threshold from the certification), so the certified detector becomes the live monitor with no hand-set constants.
Each update is transactional: a sample must be one non-empty finite real bus vector, free of text, boolean, complex, and broken-protocol aliases, and its bus count must match the established stream. The monitor copies validated samples before mutating its index or buffer, so a rejected PMU frame cannot poison a later score. Constructor controls and emitted alarm scalars are finite, non-coercive primitives; persistence is an exact positive integer.
The honest live-deployment operating point — a stream is stricter than the pre-onset window,
because a damped fault has a transient growth window the continuous monitor also alarms on —
is measured and sealed in examples/real_data/psml_modal_growth/.
grid_modal_stream ¶
A causal, real-time streaming monitor for the certified grid modal-growth detector.
The offline head-to-head (bench.grid_modal_head_to_head) certifies the grid modal
detector (monitor.grid_modal_growth): on real PMU data, at a matched false alarm,
its growth-rate σ leads instability transitions far more than chance. That
certification is done on fixed pre-onset segments — the training/validation harness.
This module is the step to the pinnacle: it runs the same detector causally on a
live stream, so the certified operating point becomes an operational early warning.
The monitor keeps a sliding window of the most recent per-bus voltage samples and, every
step, re-scores that window with the identical primitives the detector uses
(per_bus_deviation, envelope_growth_rate) — so the streaming score on a window
is bit-for-bit the offline modal_growth_score on that same window. That identity is
what makes the offline-calibrated threshold valid online: the monitor never
recalibrates, it carries the certified threshold and fires when the live σ crosses
it (after an optional persistence debounce), latching until σ falls back below so
each instability episode raises one lead event.
:meth:GridModalStreamMonitor.from_evidence closes the loop for the offline per-window
operating point: it builds the monitor from a sealed head-to-head artefact, taking the
aggregation, recency weighting, and matched-false-alarm threshold straight from the
certification — the certified detector becomes the live monitor with no hand-set
constants.
A live stream is stricter than the pre-onset window, because a damped fault has a
transient growth window the continuous monitor also alarms on, so the plain per-window
threshold over-alarms online. The r2_gate carries the fit-quality gate
(grid_modal_growth.fit_gated_growth_rate) into the live scoring: it rejects a
fault's step-like transient and holds the stream false alarm at target.
:meth:GridModalStreamMonitor.from_stream_evidence builds the monitor at the
streaming winner — window, step, persistence, threshold, and gate — read straight
from a sealed streaming operating-point artefact.
Classes¶
StreamAlarm
dataclass
¶
A lead event raised when the live growth rate σ crosses the threshold.
Attributes¶
sample_index : int
The stream sample index the alarm fired at (the last sample in the window).
time_s : float
sample_index / rate — the alarm time in seconds from the stream start.
score : float
The modal growth rate σ at the alarm window.
threshold : float
The certified matched-false-alarm threshold σ crossed.
bus : int
The most unstable bus under the focal aggregation (its per-bus σ is the
maximum), or :data:WHOLE_NETWORK_BUS under the whole-network aggregation.
GridModalStreamMonitor ¶
GridModalStreamMonitor(
*,
rate: float,
threshold: float,
window_seconds: float = 2.0,
step_seconds: float = 0.5,
aggregation: str = DEFAULT_AGGREGATION,
recency_top: float = DEFAULT_RECENCY_TOP,
persistence: int = 1,
r2_gate: float = 0.0,
)
A causal sliding-window monitor carrying the certified grid detector online.
Parameters¶
rate : float
Sampling rate in Hz; must be positive and finite.
threshold : float
The certified matched-false-alarm growth-rate threshold; σ at or above it
fires.
window_seconds : float
Sliding-window length in seconds, matching the offline segment length.
step_seconds : float
How often the window is re-scored, in seconds; must be positive.
aggregation : str
"focal" (most unstable bus) or "mean" (whole network), as certified.
recency_top : float
The recency weighting, as certified.
persistence : int
Consecutive re-scored windows at or above the threshold required before an alarm
fires; 1 fires on the first crossing. Must be a positive integer.
r2_gate : float
Fit-quality gate in [0, 1] applied to each envelope's growth rate before
aggregating (see grid_modal_growth.fit_gated_growth_rate). 0.0 (the
default) disables the gate, so the live score stays bit-for-bit the offline
modal_growth_score; the certified streaming operating point uses a
positive gate to reject a fault's step-like transient.
Raises¶
ValueError
If rate/window_seconds/step_seconds are not positive finite, the
window is shorter than two samples, persistence is below one,
aggregation is neither "focal" nor "mean", or r2_gate is not a
finite number in [0, 1].
Source code in src/scpn_phase_orchestrator/monitor/grid_modal_stream.py
Attributes¶
latest_score
property
¶
The most recent growth rate σ, or NaN before the first score.
threshold
property
¶
The certified matched-false-alarm threshold σ must reach to alarm.
window_seconds
property
¶
The effective window length in seconds (the rounded operating point).
step_seconds
property
¶
The effective re-scoring hop in seconds (the rounded operating point).
persistence
property
¶
Consecutive above-threshold windows required before an alarm fires.
Methods:¶
from_evidence
classmethod
¶
from_evidence(
evidence_path: str | Path,
*,
rate: float,
**kwargs: object,
) -> GridModalStreamMonitor
Build a monitor from a sealed head-to-head artefact.
Reads the aggregation, recency weighting, and matched-false-alarm threshold from
the certified modal record, so the live monitor carries exactly the
certified operating point with no hand-set constants.
Parameters¶
evidence_path : str or Path
Path to a sealed grid_modal_head_to_head.json artefact.
rate : float
The live stream's sampling rate in Hz.
**kwargs : object
Extra monitor arguments (window_seconds, step_seconds,
persistence).
Returns¶
GridModalStreamMonitor A monitor at the certified operating point.
Source code in src/scpn_phase_orchestrator/monitor/grid_modal_stream.py
from_stream_evidence
classmethod
¶
from_stream_evidence(
evidence_path: str | Path,
*,
rate: float,
recency_top: float = DEFAULT_RECENCY_TOP,
gate_r2: float = _CERTIFIED_STREAM_R2_GATE,
target_false_alarm: float = 0.1,
) -> GridModalStreamMonitor
Build a monitor at the certified streaming operating point.
Reads a sealed streaming operating-point artefact, selects its winning
configuration (:func:_select_stream_operating_point — the development-best
that holds the target false alarm out of sample, exactly the sealed verdict's
choice), and configures the monitor with that window, step, persistence, and
threshold, turning the fit-quality gate on iff the winner is the "r2gate"
feature. This deploys the honest streaming winner — not the more permissive
per-window operating point of :meth:from_evidence — with no hand-set
thresholds.
Parameters¶
evidence_path : str or Path
Path to a sealed grid_modal_stream_operating_point.json artefact.
rate : float
The live stream's sampling rate in Hz.
recency_top : float
The recency weighting the search was run at; defaults to the certified
:data:~scpn_phase_orchestrator.monitor.grid_modal_growth.DEFAULT_RECENCY_TOP.
The artefact does not carry it, so it is set here for transparency.
gate_r2 : float
The fit-quality gate level the search's "r2gate" feature used; defaults
to the certified value. Only applied when the winner is a gated
configuration.
target_false_alarm : float
The matched stream false-alarm target used to select the winner; must match
the artefact's target_stream_false_alarm.
Returns¶
GridModalStreamMonitor A monitor at the certified streaming operating point.
Source code in src/scpn_phase_orchestrator/monitor/grid_modal_stream.py
reset ¶
Clear the window and alarm state, as if freshly constructed.
Source code in src/scpn_phase_orchestrator/monitor/grid_modal_stream.py
update ¶
Push one per-bus voltage sample; return an alarm on a threshold crossing.
Parameters¶
sample : FloatArray
The bus-voltage magnitudes at one time step, shape (buses,).
Returns¶
StreamAlarm or None
A :class:StreamAlarm on the sample that fires a fresh lead event, else
None (still warming up, between re-scorings, below threshold, or already
latched within the same episode).
Raises¶
ValueError
If sample is not a non-empty finite real one-dimensional bus vector,
contains coercive aliases, or changes the established bus count.
Source code in src/scpn_phase_orchestrator/monitor/grid_modal_stream.py
Functions:¶
Modal Sentinel¶
ModalSentinel is the bridge-agnostic live wiring for the stream monitor: any
runtime bridge that yields one mapping of channel name to a real reading per
frame plugs in, the operating point is read only from a sealed evidence
artefact (verified before any value is trusted; a tampered artefact is
rejected), and every alarm is sealed into a hash-addressed, review-only record
carrying the operating-point provenance. Frames are fail-closed: a missing
channel, an unknown channel, or a non-finite reading rejects the frame
explicitly rather than silently degrading the monitored vector.
modal_sentinel ¶
Bridge-agnostic wiring from live channel observations to sealed alarms.
The sentinel contract: any runtime bridge that yields one Mapping of
channel name to a real reading per frame — the MQTT and OPC-UA tag bridges, the
C37118 synchrophasor bridge, or a replayed capture — plugs into
:class:ModalSentinel, which assembles the fixed channel vector, drives the
certified
:class:~scpn_phase_orchestrator.monitor.grid_modal_stream.GridModalStreamMonitor,
and seals every alarm into a hash-addressed record carrying the operating-point
provenance. The operating point is read ONLY from a sealed evidence artefact,
verified before any value is trusted; the sentinel is review-only — it observes,
records, and never actuates.
Fail-closed observation contract: a frame must carry exactly the declared channels — a missing channel, an unknown channel, or a non-finite reading rejects the frame with an explicit error rather than silently degrading the monitored vector.
Classes¶
ModalSentinel
dataclass
¶
ModalSentinel(
monitor: GridModalStreamMonitor,
channels: tuple[str, ...],
provenance: dict[str, object] = dict(),
)
Review-only live sentinel: channel observations in, sealed alarms out.
Attributes¶
monitor : GridModalStreamMonitor
The causal stream monitor carrying the certified operating point.
channels : tuple[str, ...]
The declared channel names, in the fixed vector order every frame must
satisfy.
provenance : dict[str, object]
Operating-point provenance copied into every sealed alarm record.
non_actuating : bool
Always True — the sentinel observes and never drives hardware.
execution_disabled : bool
Always True — no control action is emitted from this sentinel.
Methods:¶
from_sealed_evidence
classmethod
¶
from_sealed_evidence(
evidence_path: str | Path,
*,
case_id: str,
rate: float,
channels: tuple[str, ...],
persistence: int = 1,
) -> ModalSentinel
Build a sentinel whose operating point comes only from sealed evidence.
The threshold comes from the sealed local calibration, the aggregation and recency weighting from the sealed detector block, and the window from the named case's sealed configuration; the step is a quarter window, as evaluated. The evidence content hash and the calibration's disclosed limits are carried into every alarm's provenance.
Parameters¶
evidence_path : str | Path Path to a sealed cross-dataset evidence artefact. case_id : str The sealed corpus case whose window configuration to carry. rate : float The live stream's sampling rate in hertz. channels : tuple[str, ...] Declared channel names in fixed vector order. persistence : int Consecutive above-threshold re-scorings before an alarm fires.
Returns¶
ModalSentinel A sentinel at the sealed operating point.
Raises¶
ValueError If the seal fails to verify, the payload is not a cross-dataset evidence record, the case is not in the sealed corpus, or its window is not numeric.
Source code in src/scpn_phase_orchestrator/runtime/modal_sentinel.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
observe ¶
Consume one frame of channel readings; return a sealed alarm record.
Parameters¶
values : Mapping[str, float] One reading per declared channel, keyed by channel name. The frame must carry exactly the declared channels.
Returns¶
dict[str, object] | None
A sealed, hash-addressed alarm record when the monitor raises a
fresh alarm on this frame, else None.
Raises¶
ValueError If the frame misses a declared channel, carries an unknown channel, or any reading is boolean or not a finite real number.
Source code in src/scpn_phase_orchestrator/runtime/modal_sentinel.py
Functions:¶
load_verified_evidence ¶
Load a sealed evidence payload and verify its content hash, fail-closed.
Parameters¶
evidence_path : str | Path
Path to a sealed JSON artefact carrying a content_hash field.
Returns¶
dict[str, object] The verified payload.
Raises¶
ValueError
If the payload is not a JSON object, carries no content_hash, or
the hash does not recompute from the record — a tampered artefact
must never configure a live sentinel.