Skip to content

Feature/amplitude#55

Open
possibly-human wants to merge 7 commits intomasterfrom
feature/Amplitude
Open

Feature/amplitude#55
possibly-human wants to merge 7 commits intomasterfrom
feature/Amplitude

Conversation

@possibly-human
Copy link
Copy Markdown
Contributor

Summary

Adds a peak-detection and amplitude-analysis utility for real-time signals. The object uses a normalized Detection signal to track four event types — rising trigger crossing (PEAK_RISING), falling trigger crossing (PEAK_FALLING), local maxima (PEAK_MAX), and local minima (PEAK_MIN) — based on configurable trigger, reload, and fallback parameters. Amplitude is measured from a separate Raw signal.

The object outputs threshold-relative amplitudes (Peak-to-peak, Max above threshold, Min below threshold) using raw values paired with confirmed detect peaks, and also provides an independent Raw peak-to-peak output computed directly from raw turning points.

The peak-detection logic is adapted from Sofian Audry’s Plaquette implementation, while the raw-signal amplitude processing was added in this object.

Functionality

Inputs are:

  • Detection signal (float, ideally normalized and scaled 0 to 1)
  • Raw signal (float, original signal used for amplitude measurement)

Parameters are:

  • Trigger threshold (float between 0 and 1. Level used for rising and falling trigger crossings)
  • Reload threshold (float between 0 and 1. Level used to reset / re-arm the detector)
  • Fallback tolerance (float between 0 and 1. Drop percentage between trigger and apex required to confirm maxima and minima)
  • P2P update (enum) — updates detect-based peak-to-peak on max, min, or both

Outputs are:

  • Peak max (boolean. True when a local maximum is confirmed on the detection signal)
  • Peak min (boolean. True when a local minimum is confirmed on the detection signal)
  • Peak rising (boolean. True when the detection signal crosses upward through the trigger threshold)
  • Peak falling (boolean. True when the detection signal crosses downward through the trigger threshold)
  • Peak-to-peak (float. Held detect-based raw peak-to-peak amplitude)
  • Raw peak-to-peak (float. Held raw peak-to-peak amplitude computed from raw turning points)
  • Max above threshold (float. Held raw amplitude above the rising trigger baseline)
  • Min below threshold (float. Held raw amplitude below the falling trigger baseline)

Amplitude behavior

Detect-based amplitudes:

  • Peak-to-peak, Max above threshold, and Min below threshold use raw values paired with confirmed detect peaks
  • Suitable when amplitude should follow the peaks confirmed by the detection signal

Raw peak-to-peak:

  • Uses slope changes on the raw signal to detect turning points directly
  • Suitable when peak-to-peak amplitude should follow the raw waveform independently of the detect logic

Implementation notes

Uses a custom PeakDetector class stored in 3rdparty/extras (to be reused in Respiration and EDA processes).

Raw baselines are interpolated at trigger crossings so threshold-relative amplitudes are measured relative to the estimated raw value at the threshold crossing, not only at the nearest sample.

### Summary
Adds a peak-detection and amplitude-analysis utility for real-time signals. The object uses a normalized `Detection signal` to track four event types — rising trigger crossing (`PEAK_RISING`), falling trigger crossing (`PEAK_FALLING`), local maxima (`PEAK_MAX`), and local minima (`PEAK_MIN`) — based on configurable trigger, reload, and fallback parameters. Amplitude is measured from a separate `Raw signal`, with two available modes: `PeakLocked` or `CycleExtrema`.

Adapted from Sofian Audry’s [Plaquette implementation](https://plaquette.org/PeakDetector.html), with additional raw-amplitude tracking.

### Functionality
Inputs are:
- Detection signal (`float`, ideally normalized and scaled 0 to 1)
- Raw signal (`float`, original signal used for amplitude measurement)

Parameters are:
- Trigger threshold (`float` between 0 and 1. Level used for rising and falling trigger crossings)
- Reload threshold (`float` between 0 and 1. Level used to reset / re-arm the detector)
- Fallback tolerance (`float` between 0 and 1. Drop percentage between trigger and apex required to confirm maxima and minima)
- Amplitude mode (`enum`) — `PeakLocked` or `CycleExtrema`
- P2P update (`enum`) — updates peak-to-peak on max, min, or both

Outputs are:
- Peak max (`boolean`. True when a local maximum is confirmed on the detection signal)
- Peak min (`boolean`. True when a local minimum is confirmed on the detection signal)
- Peak rising (`boolean`. True when the detection signal crosses upward through the trigger threshold)
- Peak falling (`boolean`. True when the detection signal crosses downward through the trigger threshold)
- Peak-to-peak (`float`. Held raw peak-to-peak amplitude)
- Max above threshold (`float`. Held raw amplitude above the rising trigger baseline)
- Min below threshold (`float`. Held raw amplitude below the falling trigger baseline)

Modes explained

PeakLocked:
- Uses raw values paired with confirmed detect peaks
- Suitable when amplitude should follow the peaks confirmed by the detection signal

CycleExtrema:
- Uses raw extrema over two half-cycles: rising to falling for the upper excursion, and falling to next rising for the lower excursion
- Suitable when amplitude should follow the full raw waveform shape between trigger crossings

### Implementation notes
Uses a custom `PeakDetector` class stored in `3rdparty/extras` (to be reused in Respiration and EDA processes).

Raw baselines are interpolated at trigger crossings so amplitude is measured relative to the estimated raw value at the threshold crossing, not only at the nearest sample.
Removed CycleExtrema mode from PeakDetection and simplified the object to a single detect-based amplitude path. peak_to_peak, max_above_threshold, and min_below_threshold now all follow the detect-confirmed logic, while a new raw_peak_to_peak output is computed independently from raw slope-based turning points.
@possibly-human
Copy link
Copy Markdown
Contributor Author

possibly-human commented Apr 2, 2026

Testing

Testing for main peak detection logic was already done in previous pull request #44. Code for this part has not changed. Here, I only tested the new amplitude analysis functions.

Was tested on Linux (booted on a T2 chip, 2019 MacBook Pro)

Example file : https://drive.google.com/file/d/19X2KxdvfEoWtXr1ylX8LNEi4I0KpySqP/view?usp=sharing

Tested with live data from Sensors2OSC (acceleration). The live data was then recorded and saved with CSV recorder, and output from the Peak Detection object was compared to output from python offline processing.

peaks_and_amplitude

comparison of ossia object output and python output
peak_amplitude_compare
Peak-detector-based p2p is usually more stable, because it follows a normalized signal with threshold and fallback logic, so it is less sensitive to noise. Slope-based raw p2p is closer to the true local maxima and minima of the raw waveform, but it is more sensitive to noise and small fluctuations.

Python file
ppamplitude.py

@possibly-human possibly-human requested a review from jcelerier April 2, 2026 18:39
@jcelerier
Copy link
Copy Markdown
Member

Code looks pretty good! You should rebase on origin/master to make sure that everything is correct before merging as right now there's a few commits in master and not in here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants