I am looking at data like this:

enter image description here

Source data: http://pastebin.com/raw.php?i=L6cd8d5K

The data is quasi-periodic, there is a distinct cycle but it is not an exact repeat, and the period changes considerably. I would like to find accurate peak positions, and period durations, for each cycle. Ideally the peak positions would match the intuitive notion of where the exact peak is.

What makes this hard:

  • noise: although it may not be entirely noise! the variation is much greater when the values are high, and so the highest spikes tend to occur near where the "real" peak is.

  • the waveform is not symmetrical: neither left-to-right nor up-down. doing something like a highpass filter will move peaks up and down by an amount that depends on their duration and the shape in between.

What is unlikely to work well:

  • bandpass filter combined with conventional peak picking: the position of the peaks will shift since values from the (asymmetrical) up and down slopes is added to where the peak is. The really high values will not have a high weight in the result since the lowpass part of the bandpass filter will spread their energy to adjacent values.

  • autocorrelation: the shape of successive cycles is too different.

  • period durations measured from the leading (or trailing) edge of one cycle to the next: again shapes are too different.

  • $\begingroup$ Do you want to find the peaks of the underlying low frequency signal or of the high frequency noise? or both? $\endgroup$
    – Aaron
    Apr 25, 2014 at 16:23
  • $\begingroup$ @Aaron: the two are not necessarily separate :) there are bursts of stronger high frequency "noise" or spikes near the low frequency peaks. I want to find something similar to what a human might label the peaks as, which in many cases is the highest spike on top of the low frequency peak. $\endgroup$
    – Alex I
    Apr 25, 2014 at 17:18
  • $\begingroup$ I think you need to be more specific in your definition of peak. There are lots of different ways a human could label them. Can there be two on the same underlying low frequency cycle? $\endgroup$
    – Aaron
    Apr 25, 2014 at 19:01
  • $\begingroup$ Try findpeaks which has some really nice parameters you can use to pick the peaks. $\endgroup$
    – user16765
    Jul 25, 2015 at 14:20
  • $\begingroup$ i wouldn't write off auto-correlation so summarily. also try a DC-blocking filter (subtract a well-aligned moving-average DC) to see what your data would look like. $\endgroup$ Jul 25, 2015 at 17:12

3 Answers 3


Personally, I would just use a lowpass filter try and keep it as small as possible to reduce the effect of asymmetry.

The fact that there is significant noise already implies some uncertainty in the peak position, I expect this will be of similar or greater magnitude to any bias the filter introduces.

If you are really concerned about the bias you could look at using morphological opening and closing filters. This is basically running a ball over/under the surface so either one will over/underestimate the peak height. You can then get 2 lines to give an envelope of where the peak may lie. The average of the two curves is probably a decent estimate of the "true" curve prodived the noise frequency is suitably high.


You could try a Savitzky-Golay filter, followed by standard peak detection. The S-G filter will preserve the location of your peaks. If you're using Matlab it comes with the signal processing toolbox. See here. If you're using python I wrote about them here.


As @Aaron said your peak definition is not very clear, but if you want to find the time position of the highest amplitudes that satisfies certain threshold condition, then I think a useful tool to extract that information is the STFT and specially if you are dealing with noise the Gabor Transform.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.