Find the dominant low frequency I have this signal, with an arbitrary x-axis, and I want to find the (visually) dominant frequency of the signal. There may be a high frequency component, but I'm interested in the component with a period of around 120 pixels.



First I implemented the Pisarenko Harmonic Decomposition, but only got a very high frequency out (0.04 Hz) (one bin, one second). The I tried with the Fourier transform, and when I plotted the frequency amplitude spectrum I also only got a range of very high frequencies.



Can someone help me solve this problem? What am I doing wrong? It feels like such a simple problem, but for some reason I just can't solve it.

The raw dataset is located here: http://pastebin.com/5ghKbBRm
Have a look at the Python code below. It calculates the auto-correlation of the data, after the DC part of the signal was removed. The autocorrelation shows nice peaks with much less noise than the original signal. Then, we detect the local maxima and measure the distance between them. This distance is then the estimated period of your signal:

import csv
import requests
import numpy as np
from io import BytesIO
from scipy import signal

url = 'http://pastebin.com/raw/5ghKbBRm'
response = requests.get(url)
A = np.genfromtxt(BytesIO(response.content)) # read the CSV file

# begin signal processing

A = A - np.mean(A)  # remove the DC part of the signal
plt.subplot(121)
plt.plot(A)

plt.subplot(122)
C = np.correlate(A, A, 'same')  # calculate autocorrelation to smooth out the noise
plt.plot(C)

plt.subplot(122)
P = signal.argrelextrema(C, np.greater)[0]  # caluclate local maxima (this step can be improved)
P = P[C[P]&gt;15000] # filter maxima, where the autocorrelation values is too low
plt.stem(P, 30000*np.ones_like(P))  # plot where the detected peaks are

print ("Peak distances: ", np.diff(P))  # calculate distance between peaks and the mean of the distances
print ("Estimated period: ", np.mean(np.diff(P)))


Program output: 

Peak distances:  [117 118 117 117 117 117 118 117]
Estimated period:  117.25




There is room for improvement. For example, the detection of local maxima is not very robust and the threshold was set manually, but this should enable you to find out the rest on your own.