-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference: Event Detection
The EventDetection library groups threshold violations into discrete events with statistics, provides console reporting, and includes a Gantt-style viewer UI with click-to-plot functionality. Features include severity escalation, persistent event storage with backups, and live auto-refresh from file.
Core detection engine. Groups consecutive threshold violation points into Event objects, applies debounce filtering, computes statistics, and invokes callbacks.
det = EventDetector();
det = EventDetector('MinDuration', 0.5);
det = EventDetector('MinDuration', 2, 'OnEventStart', @myCallback, 'MaxCallsPerEvent', 3);| Property | Type | Default | Description |
|---|---|---|---|
MinDuration |
double | 0 |
Debounce filter: discard events shorter than this (in time units matching your X data). Set to 0 to keep all events |
OnEventStart |
function_handle | [] |
Callback invoked as f(event) for each detected event |
MaxCallsPerEvent |
double | 1 |
Maximum callback invocations per event (prevents duplicate notifications) |
Detect events from raw time series data and a threshold.
events = det.detect(t, values, 4.5, 'high', 'High Limit', 'Pressure');
events = det.detect(t, values, -2.0, 'low', 'Low Limit', 'Temperature');| Parameter | Type | Description |
|---|---|---|
t |
1xN double | Time stamps |
values |
1xN double | Data values |
thresholdValue |
double | Threshold to check against |
direction |
char |
'high' (value > threshold) or 'low' (value < threshold) |
thresholdLabel |
char | Label for the threshold (e.g., 'Run HI') |
sensorName |
char | Name of the sensor/channel |
Returns: Array of Event objects. Returns [] if no events are found.
Algorithm:
- Call the private helper
groupViolations()to find all points where the value crosses the threshold in the given direction, and cluster consecutive violation points into groups (each group has astartIdxandendIdx) - For each group, compute
startTime,endTime, andduration - Filter out events shorter than
MinDuration(debounce) - Compute statistics for each event over the data window
values(startIdx:endIdx):-
PeakValue:
maxfor'high'direction,minfor'low'direction - NumPoints, MinValue, MaxValue, MeanValue, RmsValue, StdValue
-
PeakValue:
- Invoke
OnEventStartcallback for each event (respectingMaxCallsPerEvent)
% Simple detection
det = EventDetector('MinDuration', 0.5);
t = linspace(0, 100, 1e6);
y = randn(1, 1e6) * 10 + 50;
events = det.detect(t, y, 70, 'high', 'High', 'Pressure');
fprintf('Found %d events\n', numel(events));% With live logging callback
det = EventDetector('MinDuration', 1.0, 'OnEventStart', eventLogger());
events = det.detect(t, y, 70, 'high', 'High', 'Pressure');
% Console output: [EVENT] Pressure | High | HIGH | 12.50 -> 14.20 (dur=1.70) | peak=82.30Value class holding metadata and statistics for a single detected event.
| Constant | Value | Description |
|---|---|---|
DIRECTIONS |
{'high', 'low'} |
Valid direction values |
| Property | Type | Description |
|---|---|---|
StartTime |
double | Timestamp of first violation point |
EndTime |
double | Timestamp of last violation point |
Duration |
double | EndTime - StartTime |
SensorName |
char | Name of the sensor/channel |
ThresholdLabel |
char | Label of the threshold that was violated |
ThresholdValue |
double | The threshold value |
Direction |
char |
'high' or 'low'
|
PeakValue |
double | Worst violation value (furthest from threshold) |
NumPoints |
double | Number of data points within the event time window |
MinValue |
double | Minimum signal value during event |
MaxValue |
double | Maximum signal value during event |
MeanValue |
double | Mean signal value during event |
RmsValue |
double | RMS signal value during event |
StdValue |
double | Standard deviation during event |
e = Event(startTime, endTime, sensorName, thresholdLabel, thresholdValue, direction);| Parameter | Type | Description |
|---|---|---|
startTime |
double | First violation timestamp |
endTime |
double | Last violation timestamp (must be >= startTime) |
sensorName |
char | Sensor/channel name |
thresholdLabel |
char | Threshold label |
thresholdValue |
double | Threshold value |
direction |
char | Must be 'high' or 'low'
|
Errors:
-
Event:invalidDirectionif direction is not'high'or'low' -
Event:invalidTimeRangeifendTime < startTime
Note: Event objects are normally created by EventDetector.detect(), not directly.
Set the statistical fields. Called internally by EventDetector. Since Event is a value class, this returns a new object with the stats set.
e = e.setStats(peakVal, nPts, minVal, maxVal, meanVal, rmsVal, stdVal);Escalate an event to a higher severity threshold. Used by the severity escalation system. Returns a new Event with updated label and threshold value while preserving all other fields and statistics.
e = e.escalateTo('temp critical', 95);| Parameter | Type | Description |
|---|---|---|
newLabel |
char | New threshold label |
newThresholdValue |
double | New threshold value |
Configuration container that orchestrates event detection across multiple sensors. Bridges the SensorThreshold and EventDetection libraries. Supports severity escalation, persistent event storage with backups, and auto-open viewer.
cfg = EventConfig();| Property | Type | Default | Description |
|---|---|---|---|
Sensors |
cell array | {} |
Registered Sensor objects |
SensorData |
struct array | [] |
Sensor data for viewer (fields: name, t, y) |
MinDuration |
double | 0 |
Debounce threshold |
MaxCallsPerEvent |
double | 1 |
Callback limit |
OnEventStart |
function_handle | [] |
Callback f(event)
|
ThresholdColors |
containers.Map | (empty) | Maps threshold labels to RGB color vectors |
AutoOpenViewer |
logical | false |
Auto-open EventViewer after detection |
EscalateSeverity |
logical | true |
Escalate events whose peak exceeds a higher threshold on the same sensor/direction |
EventFile |
char | '' |
Path to .mat file for auto-saving events. Empty = disabled |
MaxBackups |
double | 5 |
Number of timestamped backup files to keep before pruning. 0 = no backups |
Register a sensor. Automatically calls sensor.resolve() and stores the sensor's data (X, Y, and display name) for the viewer's click-to-plot feature.
cfg.addSensor(sensor);Set the display color for a threshold label in the viewer.
cfg.setColor('Run HI', [1 0 0]);
cfg.setColor('Boost HI', [1 0.5 0]);Create a configured EventDetector from the config properties.
det = cfg.buildDetector();Detect events across all registered sensors, then:
-
Severity escalation (if
EscalateSeverityistrue): for each event, check if its peak exceeds a higher threshold on the same sensor and direction. If so, escalate the event's label and threshold value to the higher one. Remove duplicate events that are contained within an escalated event with the same label. -
Auto-save (if
EventFileis set): create a timestamped backup of the existing file, then save events, sensor data, threshold colors, and a timestamp to the.matfile. Old backups are pruned toMaxBackups. -
Auto-open viewer (if
AutoOpenVieweristrue).
events = cfg.runDetection();Returns: Combined Event array across all sensors, after escalation.
When nested thresholds exist (e.g., warning at 85, critical at 95), detection runs each threshold independently. A brief spike above 95 may get debounced, but the longer warning event (above 85) survives. Without escalation, the user sees a "temp warning" with peak=96 — misleading.
With EscalateSeverity = true (default), the post-detection step checks the warning event's peak against all higher thresholds for the same sensor and direction. Since 96 > 95, the event is escalated from "temp warning" to "temp critical".
cfg.EscalateSeverity = true; % default — escalate
cfg.EscalateSeverity = false; % disable — keep original labelsHow it works for each direction:
-
'high': thresholds sorted ascending. Peak must exceed (>=) the higher threshold value. -
'low': thresholds sorted descending. Peak must be at or below (<=) the lower threshold value.
Set EventFile to auto-save events to a .mat file after every runDetection() call.
cfg.EventFile = 'my_events.mat';
cfg.MaxBackups = 5; % keep 5 timestamped backups (default)
cfg.MaxBackups = 0; % disable backups
events = cfg.runDetection(); % saves automaticallyThe .mat file contains:
| Field | Type | Description |
|---|---|---|
events |
Event array | All detected events |
sensorData |
struct array | Sensor time series (name, t, y) |
thresholdColors |
struct | Color map serialized as struct (label + rgb per entry) |
timestamp |
datetime | When the file was saved |
Backup files are created with a timestamp suffix before each overwrite:
my_events.mat ← current
my_events_20260309_143025.mat ← backup 1
my_events_20260309_142512.mat ← backup 2
Oldest backups are pruned when the count exceeds MaxBackups.
cfg = EventConfig();
cfg.MinDuration = 0.5;
cfg.OnEventStart = eventLogger();
cfg.EventFile = 'events.mat';
cfg.MaxBackups = 3;
cfg.addSensor(pressureSensor);
cfg.addSensor(temperatureSensor);
cfg.setColor('Run HI', [1 0 0]);
cfg.setColor('Boost HI', [1 0.5 0]);
events = cfg.runDetection();
% Events saved to events.mat with backup of previous versionFigure-based UI with a Gantt-style timeline, filter dropdowns, and a filterable event table. Supports click-to-plot for zooming into individual events via FastPlot with violation markers and toolbar.
viewer = EventViewer(events);
viewer = EventViewer(events, sensorData);
viewer = EventViewer(events, sensorData, thresholdColors);| Parameter | Type | Description |
|---|---|---|
events |
Event array | Detected events to display |
sensorData |
struct array | Fields: name, t, y (enables click-to-plot). Optional |
thresholdColors |
containers.Map | Maps threshold labels to [R G B] color vectors. Optional |
| Property | Type | Description |
|---|---|---|
Events |
Event array | All events (unfiltered) |
SensorData |
struct array | Sensor time series data for click-to-plot |
ThresholdColors |
containers.Map | Color mapping for threshold labels |
hFigure |
figure handle | Handle to the viewer figure |
Refresh the viewer with new events. Re-applies current filters, redraws the timeline, and repopulates the table.
viewer.update(newEvents);Get unique sensor names or threshold labels from the current events.
names = viewer.getSensorNames();
labels = viewer.getThresholdLabels();Reload events, sensor data, and colors from the source .mat file. Only available when the viewer was opened via fromFile(). Updates the Gantt chart, table, and status bar.
viewer.refreshFromFile();Start polling the source .mat file at the given interval (in seconds).
viewer.startAutoRefresh(5); % refresh every 5 secondsStop the auto-refresh timer.
viewer.stopAutoRefresh();Open an EventViewer directly from a saved .mat event store file (created by EventConfig with EventFile set). No sensors or config needed — all data is loaded from the file.
viewer = EventViewer.fromFile('events.mat');The viewer includes a refresh toolbar (only when opened via fromFile):
| Control | Description |
|---|---|
| [Refresh] button | Manual one-shot reload from file |
| [Auto] checkbox | Enable/disable auto-refresh timer |
| Interval input | Refresh interval in seconds (default 5) |
| Status bar | Shows last refresh time, event count, and source file path |
The figure title displays the timestamp from the saved file.
The viewer opens a figure window (1200x700, dark theme) with three sections:
Top Panel — Gantt Timeline:
- One row per sensor on the Y-axis, bars fill the full lane height (no gaps)
- Colored horizontal bars for each event
- Bar color is determined by
ThresholdColorsif a mapping exists, otherwise auto-assigned - X and Y grid lines in subtle gray for visual alignment
- Hover tooltips: hovering over a bar shows sensor name, threshold, direction, start/end times, duration, peak value, and point count
- Click-to-select: clicking a Gantt bar highlights it with a white border and highlights the corresponding table row with a blue background
Filter Dropdowns (middle):
- Sensor dropdown: filter by sensor name (or "All")
- Threshold dropdown: filter by threshold label (or "All")
- Changing either filter immediately redraws the timeline and table
Refresh Toolbar (when opened via fromFile):
- Refresh button, Auto checkbox, interval input, status bar
Bottom Panel — Event Table:
| Column | Description |
|---|---|
| Start | Event start time |
| End | Event end time |
| Duration | Event duration |
| Sensor | Sensor name |
| Threshold | Threshold label |
| Dir | Direction (high or low) |
| Peak | Peak violation value |
| #Pts | Number of data points in event |
| Min | Minimum value during event |
| Max | Maximum value during event |
| Mean | Mean value during event |
| RMS | RMS value during event |
| Std | Standard deviation during event |
Click-to-Plot:
Clicking any row in the table opens a new FastPlot window with:
- The sensor's full signal via
addLine - The violated threshold via
addThresholdwithShowViolationsenabled -
FastPlotToolbarfor interactive exploration - View zoomed to the event's time range with 20% padding
Requires SensorData to be provided.
% Direct usage with events
viewer = EventViewer(events, sensorData, colors);
viewer.update(newEvents); % live update% Open from saved file (e.g., from background detection process)
viewer = EventViewer.fromFile('events.mat');
% Manual refresh
viewer.refreshFromFile();
% Auto-refresh every 5 seconds
viewer.startAutoRefresh(5);
% Stop auto-refresh
viewer.stopAutoRefresh();% Background process writes events, viewer polls them:
%
% Process A (background):
% cfg.EventFile = '/shared/events.mat';
% while running
% cfg.runDetection(); % auto-saves to file
% pause(10);
% end
%
% Process B (viewer):
% viewer = EventViewer.fromFile('/shared/events.mat');
% viewer.startAutoRefresh(5); % polls every 5sBridge function that connects the SensorThreshold and EventDetection libraries.
events = detectEventsFromSensor(sensor); % Default EventDetector
events = detectEventsFromSensor(sensor, detector); % Custom detectorBehavior:
- Determines the sensor display name (
sensor.Nameif set, otherwisesensor.Key) - Iterates over
sensor.ResolvedViolations - Maps SensorThreshold directions:
'upper'→'high','lower'→'low' - Looks up threshold value from
sensor.ResolvedThresholds - Calls
detector.detect()on the full sensor signal for each threshold
Print a formatted event summary table to the console.
printEventSummary(events);Output format:
Start End Duration Sensor Threshold Dir Peak #Pts Mean Std
------------------------------------------------------------------------------------------------------------------------
12.50 14.20 1.70 Pressure Run HI high 82.30 170 75.40 4.21
...
2 event(s) total.
Factory function returning a callback for live console logging of events.
det = EventDetector('OnEventStart', eventLogger());Output: [EVENT] Pressure | Run HI | HIGH | 12.50 -> 14.20 (dur=1.70) | peak=82.30
Clusters consecutive threshold violations into groups using diff([0, mask, 0]) transition detection.
Returns: Struct array with startIdx and endIdx per group. Returns [] if no violations.
%% 1. Create sensors with thresholds
sTemp = Sensor('temperature', 'Name', 'Temperature');
sTemp.X = t; sTemp.Y = temp;
sTemp.addThresholdRule(struct(), 85, 'Direction', 'upper', 'Label', 'temp warning');
sTemp.addThresholdRule(struct(), 95, 'Direction', 'upper', 'Label', 'temp critical');
sPres = Sensor('pressure', 'Name', 'Pressure');
sPres.X = t; sPres.Y = pressure;
sPres.addThresholdRule(struct(), 4, 'Direction', 'lower', 'Label', 'pressure low');
%% 2. Configure detection with auto-save and escalation
cfg = EventConfig();
cfg.MinDuration = 0.5;
cfg.OnEventStart = eventLogger();
cfg.EventFile = 'events.mat'; % persistent storage
cfg.MaxBackups = 3; % keep 3 backups
cfg.addSensor(sTemp);
cfg.addSensor(sPres);
cfg.setColor('temp warning', [1.0 0.8 0.0]);
cfg.setColor('temp critical', [1.0 0.2 0.0]);
cfg.setColor('pressure low', [0.2 0.5 1.0]);
%% 3. Detect — events are escalated and saved to file
events = cfg.runDetection();
printEventSummary(events);
%% 4. View from file (e.g., in another session or by another user)
viewer = EventViewer.fromFile('events.mat');
viewer.startAutoRefresh(5); % poll for updates every 5s- API Reference: Sensors — Sensor, StateChannel, ThresholdRule
- API Reference: FastPlot — addSensor(), addLine(), addThreshold() methods
- Live Mode Guide — Live event detection with streaming data
-
Examples —
example_event_detection_live,example_event_viewer_from_file
FastPlot Wiki
API Reference
Guides
Use Cases
Internals
Resources