In my recent work I've came across a problem where I need to find certain points in quickly oscillating data. Let's work with syntethic data instead of real measurements and ignore the noise for the time being. These points are called stationary phase points (SPP for short). For human eye they are quite easy to spot: the oscillation slows down locally. An example:
Some important things to note:
It's always a local maxima or minima (so a reliable peak detection algorithm can help a lot, which I've been working on recently)
The graph is ideally normalized to [-1, 1], in real measurements it's a little distorted
Usually the Nyquist–Shannon sampling theorem is not satisfied at the borders of data and the oscillation is avaraged out. (In the synthetic data I created it's satisfied, see below for a real-world dataset.)
The general number of SPPs are 1 or 2, 3 or 4 are really rare, but exist.
A SPP can continiously move around in the x direction as conditions are changing, can vanish at the borders of x-axis, and also one SPP can separate into two different SPPs which are moving away from each other.
The main goal would be reliably monitoring these points movement (ideally in real time, but first the SPP detection from x-y data is the target). There are some other generated graphs with indication for SPPs, and the last is from real data.
To solve this, my first thought is to detect all the extremal points in data, then generate their consecutive distances, and where that distance exceeds a certain threshold value, it's a SPP. But setting a good threshold, correctly identifying extremal points seems quite hard and unique for each graph.
My question is: Do you think it would worth using a machine learning tool there, and if yes, which algorithm would be the most suitable? As a physicist I'm inexperienced, I only have basic knowledge about ML (but willing to learn!) In general, can you think of any useful algorithm or idea for such situation?
Note: Mostly I'm working in Python with numpy/scipy.
As far as local max and min detection concerned I use scipy.signal.find_peaks
and scipy.signal.find_peaks_cwt
along with scipy.signal.savgol_filter
.