FFT on non-periodic signal and signal power at each harmonic - is there a more robust approach?

I have a non-periodic signal collected from a force plate, it represents the foot/ground contact of a human when running.

My aim is to calculate the signal power of each harmonic up to 50Hz. I will break down what I have done so far.

1. Firstly, I calculate the fundamental frequency by dividing the sampling frequency by the length of the signal. I then find the other harmonics by multiplying the fundamental frequency by 2,3...etc (not shown here, this example just includes the fundamental frequency (FF).

Fs = 1000;
FF = Fs/(length(Fz_data));

2. I run the FFT on my signal.

dt = 1/Fs;
t=(0:1/Fs:(length(Fz_data)-1)/Fs)';
NFFT = length(Fz_data);
Y = fft(Fz_data,NFFT);

3. For each harmonic (identified in 1 - FF in this instance),I zero out frequencies above and below the harmonic and then run ifft to convert the data back to the time domain which leaves me with the data for the first harmonic only(?).

F = ((0:1/NFFT:1-1/NFFT)*Fs).';
Y(F<FF-0.1) = 0;
Y(F>FF+0.1) = 0;
y = ifft(Y,NFFT,'symmetric');


1. I then calculate the power of this signal using pwelch.

[P,~] = pwelch(y,ones(NFFT,1),0,NFFT,Fs,'power');
pwr = sum(P)


Questions

From a programming perspective, this works, but I have reservations that this approach is not based on sound theory. I will, therefore, present some questions below, and I hope the community may be able to offer some solutions to improve the robustness of this approach.

1. Is it suitable to calculate the fundamental frequency from the length of the signal?

2. I have read that it is not suitable to use an FFT on a non-periodic signal. Is there a way to adapt the FFT method to make it more suitable e.g. some sort of windowing function?

3. Is there an easy way to remove drift/bias from the signal?

4. I would also welcome comments on any other aspects of this process if you feel it would make it more robust.

• Regarding point #1) You can't calculate the fundamental frequency (or whatever you want to call it) by dividing the sampling freqency by the signal length. This would lead to decreasing frequencies with longer signals (and vice versa). Instead, you should use FFT or autocorrelation ( and even zero crossing rate is sufficient in some simple cases) – dsp_user Jan 29 '18 at 13:26
• @dsp_user Thank you for your insight. In the example above, as the beginning and end of this signal are zero, then the length of the signal is the same as the zero crossing rate. In that case, is this OK? But I do note that Tendero below has noted that a fundamental frequency cannot be calculated from non-periodic waveform - in that case, do you know what would be the equivalent naming convention for this frequency in a non-periodic waveform - if I can identify the correct terminology I can ensure I am researching the correct terms? – Tim Blackmore Jan 30 '18 at 9:37
• I don't mind calling it a fundamental frequency. Of course, for non-periodic signals you don't have a single fundamental frequency but if you split your signal into smaller sections (which are often considered periodic), then we can still retain the terminology applicable to periodic signals (human speech being such one example) – dsp_user Jan 30 '18 at 10:48
• Regarding the zero crossing rate method, in order to determine the frequency using the ZCR, you should use the well-know equation f=1/T (where T is the frequency period). However, this also means that you should have a waveform and I'm not sure that you have a waveform to begin with. – dsp_user Jan 30 '18 at 11:08
• @dsp_user thanks again for your comments. Would you consider the use of the periodogram a suitable alternative? With the largest peak being identified as the FF? e.g... [pxx,f] = periodogram(Fz_data,[],[],fs); – Tim Blackmore Jan 30 '18 at 13:50

Is it suitable to calculate the fundamental frequency from the length of the signal?

Your signal is not periodic, so speaking of "fundamental frequency" is not correct. The fundamental frequency corresponds to the lowest frequency of a periodic waveform, which is not the case here. So, regarding your question, no: you cannot define a fundamental frequency from the length of a signal - two things not related at all.

I have read that it is not suitable to use an FFT on a non-periodic signal. Is there a way to adapt the FFT method to make it more suitable e.g. some sort of windowing function?

FFT can indeed be used for non-periodic signals. In case you are not too familiar with DFT, I'll try to explain how it works in a nutshell.

You have a discrete signal. You window it (you only take $N$ of its values). You perform the DFT on those values. What does "perform the DFT" mean? The signal whose DFT will be calculated is assumed to be $N$-periodic, and you get a discrete frequency representation of that signal (not the original non-windowed one). I believe that this is the reason why you state that FFT is not suitable on non-periodic signals. Nevertheless, you can still use it, we do it all the time. Maybe some answers in this question can help.

If you are interested in which frequencies are present at each instant of time, one can use several windows an overlap them, and take the FFTs of those signals. See STFT.

Is there an easy way to remove drift/bias from the signal?

Do you mean DC value? In that case, you can just substract the mean value of the signal, or apply a high-pass filter with sufficiently low cutoff frequency.

I would also welcome comments on any other aspects of this process if you feel it would make it more robust.

At some point in your script, you just set some FFT coefficients to zero. Note that this approach is generally not a good idea.

• thanks for your comments. Can I ask a further question with regards to your last point about zeroing bins? After reading your linked articles, I can see that I am causing problems for myself. What would you consider to be a more appropriate method for identifying bands in a signal of a certain frequency - perhaps a bandpass filter? – Tim Blackmore Feb 1 '18 at 9:23
• @TimBlackmore If you are interested in keeping only a limited range of frequencies of your original signal, then yes - a bandpass filter is the way to go. – Tendero Feb 1 '18 at 12:24