Skip to content

API Reference: Event Detection

Hannes Suhr edited this page Mar 9, 2026 · 15 revisions

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.


EventDetector

Core detection engine. Groups consecutive threshold violation points into Event objects, applies debounce filtering, computes statistics, and invokes callbacks.

Constructor

det = EventDetector();
det = EventDetector('MinDuration', 0.5);
det = EventDetector('MinDuration', 2, 'OnEventStart', @myCallback, 'MaxCallsPerEvent', 3);

Properties

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)

Methods

detect(t, values, thresholdValue, direction, thresholdLabel, sensorName)

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:

  1. 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 a startIdx and endIdx)
  2. For each group, compute startTime, endTime, and duration
  3. Filter out events shorter than MinDuration (debounce)
  4. Compute statistics for each event over the data window values(startIdx:endIdx):
    • PeakValue: max for 'high' direction, min for 'low' direction
    • NumPoints, MinValue, MaxValue, MeanValue, RmsValue, StdValue
  5. Invoke OnEventStart callback for each event (respecting MaxCallsPerEvent)

Usage Example

% 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.30

Event

Value class holding metadata and statistics for a single detected event.

Constants

Constant Value Description
DIRECTIONS {'high', 'low'} Valid direction values

Properties (all read-only, SetAccess = private)

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

Constructor

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:invalidDirection if direction is not 'high' or 'low'
  • Event:invalidTimeRange if endTime < startTime

Note: Event objects are normally created by EventDetector.detect(), not directly.

Methods

setStats(peakValue, numPoints, minVal, maxVal, meanVal, rmsVal, stdVal)

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);
Parameter Type Description
peakValue double Worst violation value
numPoints double Number of data points
minVal double Minimum value
maxVal double Maximum value
meanVal double Mean value
rmsVal double RMS value
stdVal double Standard deviation

EventConfig

Configuration container that orchestrates event detection across multiple sensors. Bridges the SensorThreshold and EventDetection libraries.

Constructor

cfg = EventConfig();

Properties

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

Methods

addSensor(sensor)

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);
Parameter Type Description
sensor Sensor A Sensor object with data and threshold rules configured

Behavior:

  • Calls sensor.resolve() to compute thresholds and violations
  • Appends the sensor to cfg.Sensors
  • Stores {name, t, y} in cfg.SensorData (uses sensor.Name if set, otherwise sensor.Key)

setColor(label, rgb)

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]);
Parameter Type Description
label char Threshold label
rgb 1x3 double RGB color vector, values in [0, 1]

buildDetector()

Create a configured EventDetector from the config's MinDuration, MaxCallsPerEvent, and OnEventStart properties.

det = cfg.buildDetector();

Returns: A configured EventDetector instance.

runDetection()

Detect events across all registered sensors. Iterates over each sensor, calls detectEventsFromSensor(), and concatenates the results.

events = cfg.runDetection();

Returns: Combined Event array across all sensors.

Behavior:

  • Builds a detector via buildDetector()
  • Calls detectEventsFromSensor(sensor, det) for each sensor in cfg.Sensors
  • If AutoOpenViewer is true and events were found, opens an EventViewer with cfg.SensorData and cfg.ThresholdColors

Usage Example

cfg = EventConfig();
cfg.MinDuration = 0.5;
cfg.OnEventStart = eventLogger();
cfg.AutoOpenViewer = true;

cfg.addSensor(pressureSensor);
cfg.addSensor(temperatureSensor);

cfg.setColor('Run HI', [1 0 0]);
cfg.setColor('Boost HI', [1 0.5 0]);

events = cfg.runDetection();

EventViewer

Figure-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.

Constructor

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

Properties

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

Public Methods

update(newEvents)

Refresh the viewer with new events. Re-applies current filters, redraws the timeline, and repopulates the table. Useful for live mode.

viewer.update(newEvents);

getSensorNames()

Get unique sensor names from the current events.

names = viewer.getSensorNames();
% Returns cell array of char, e.g. {'Pressure', 'Temperature'}

getThresholdLabels()

Get unique threshold labels from the current events.

labels = viewer.getThresholdLabels();
% Returns cell array of char, e.g. {'Run HI', 'Boost HI'}

UI Layout

The viewer opens a figure window (1200x700, dark theme) with three sections:

Top Panel -- Gantt Timeline:

  • One row per sensor on the Y-axis
  • Colored horizontal bars for each event
  • Bar color is determined by ThresholdColors if a mapping exists for the event's threshold label, otherwise auto-assigned from a built-in palette
  • X-axis represents time
  • Very short events are drawn with a minimum width for visibility

Filter Dropdowns (middle):

  • Sensor dropdown: filter events by sensor name (or "All")
  • Threshold dropdown: filter events by threshold label (or "All")
  • Changing either filter immediately redraws the timeline and table

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

Hover Tooltips:

Hovering over any bar in the Gantt timeline displays a tooltip with event details: sensor name, threshold label, direction, start/end times, duration, peak value, and point count. The tooltip follows the cursor and disappears when the mouse leaves the bar. The tooltip uses a dark background with monospace font for readability.

Grid Lines:

The Gantt timeline displays both X (time) and Y (sensor) grid lines for easier visual alignment of events across sensors. Grid lines are rendered in a subtle gray ([0.4 0.4 0.4] at 50% alpha).

Click-to-Plot:

Clicking any row in the table opens a new FastPlot window showing the sensor's full signal (addLine), the violated threshold (addThreshold), and zoomed to the event's time range with 20% padding on each side. Requires SensorData to be provided.

Usage Example

sensorData = struct();
sensorData(1).name = 'Pressure';
sensorData(1).t = pressureTime;
sensorData(1).y = pressureValues;
sensorData(2).name = 'Temperature';
sensorData(2).t = tempTime;
sensorData(2).y = tempValues;

colors = containers.Map();
colors('Run HI') = [1 0 0];
colors('Boost HI') = [1 0.5 0];

viewer = EventViewer(events, sensorData, colors);

% Later, update with new events (live mode)
viewer.update(newEvents);

Convenience Functions

detectEventsFromSensor(sensor, detector)

Bridge function that connects the SensorThreshold and EventDetection libraries. Uses a sensor's resolved thresholds and violations to detect events.

events = detectEventsFromSensor(sensor);           % Default EventDetector
events = detectEventsFromSensor(sensor, detector);  % Custom detector
Parameter Type Description
sensor Sensor A resolved Sensor object (with ResolvedViolations and ResolvedThresholds)
detector EventDetector Optional. A configured detector. Defaults to EventDetector() with default settings

Returns: Combined Event array across all of the sensor's thresholds.

Behavior:

  1. Determines the sensor display name (sensor.Name if set, otherwise sensor.Key)
  2. Iterates over sensor.ResolvedViolations
  3. Maps SensorThreshold directions to EventDetection directions: 'upper' becomes 'high', 'lower' becomes 'low'
  4. Looks up the threshold value from sensor.ResolvedThresholds by matching on label and direction
  5. Calls detector.detect() on the full sensor signal (sensor.X, sensor.Y) for each threshold
  6. Concatenates and returns all detected events

Note: Requires sensor.resolve() to have been called beforehand.

printEventSummary(events)

Print a formatted event summary table to the console.

printEventSummary(events);

If events is empty, prints No events detected.

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
45.80        47.10        1.30       Pressure         Run HI             high      78.60    130      73.20       3.85
...

2 event(s) total.

Note: Long sensor names and threshold labels are truncated to 16 and 18 characters respectively.

eventLogger()

Factory function that returns a function handle for live console logging of events. Intended to be passed as the OnEventStart callback.

det = EventDetector('OnEventStart', eventLogger());

Output format (one line per event):

[EVENT] Pressure | Run HI | HIGH | 12.50 -> 14.20 (dur=1.70) | peak=82.30

Private Helpers

groupViolations(t, values, thresholdValue, direction)

Private function used internally by EventDetector.detect(). Clusters consecutive threshold violations into groups.

groups = groupViolations(t, values, thresholdValue, direction);
Parameter Type Description
t 1xN double Time stamps (unused in grouping, but part of the signature)
values 1xN double Data values
thresholdValue double Threshold value
direction char 'high' (value > threshold) or 'low' (value < threshold)

Returns: Struct array with fields startIdx and endIdx, one element per contiguous group of violating points. Returns [] if no violations are found.

Algorithm:

  1. Compute boolean mask: values > thresholdValue for 'high', values < thresholdValue for 'low'
  2. Detect transitions using diff([0, mask, 0]): rising edges mark group starts, falling edges mark group ends
  3. Return start and end indices for each contiguous group

Complete Workflow Example

%% 1. Create a sensor with state-dependent thresholds
s = Sensor('pressure', 'Name', 'Chamber Pressure');
s.X = linspace(0, 100, 1e6);
s.Y = randn(1, 1e6) * 10 + 50;

sc = StateChannel('machine');
sc.X = [0 30 60 80];
sc.Y = [0 1 2 1];
s.addStateChannel(sc);

s.addThresholdRule(struct('machine', 1), 70, 'Direction', 'upper', 'Label', 'Run HI');
s.addThresholdRule(struct('machine', 2), 55, 'Direction', 'upper', 'Label', 'Boost HI');
s.resolve();

%% 2. Configure event detection
cfg = EventConfig();
cfg.MinDuration = 0.5;
cfg.OnEventStart = eventLogger();
cfg.AutoOpenViewer = true;

cfg.addSensor(s);

cfg.setColor('Run HI', [1 0 0]);
cfg.setColor('Boost HI', [1 0.5 0]);

%% 3. Detect events and view results
events = cfg.runDetection();
% Console output from eventLogger:
%   [EVENT] Chamber Pressure | Run HI | HIGH | 31.20 -> 33.50 (dur=2.30) | peak=82.10
%   [EVENT] Chamber Pressure | Boost HI | HIGH | 61.40 -> 62.80 (dur=1.40) | peak=68.70
%   ...

% EventViewer opens automatically (AutoOpenViewer = true)

%% 4. Print summary to console
printEventSummary(events);

%% 5. Plot the sensor with thresholds in FastPlot
fp = FastPlot('Theme', 'dark');
fp.addSensor(s, 'ShowThresholds', true);
fp.render();

See Also

Clone this wiki locally