Reputation: 486
I would like to plot profile of rugosity (from AFM measurements) but there are still this that I misunderstand regarding the FFT (especially in Matlab documentation).
I want to compare two measurements, a.k.a. two rugosity profiles. They were done on the same surface, they only diverge on the fact that one is made on a shorter length than the other one. For each profile though, I have the same number of sample measures (N=512 here). Let's say these are my profiles, t10
and t100
being the x-abscisse along which the measure is made, and d10
and d100
being the vertical coordinate, a.k. the height of the measurement in the rugosity profile.
N=512;
t10 = linspace(0,10, N);
t100= linspace(0,100, N);
d10 = sin(2*pi*0.23 .*t10)+cos(2*pi*12 .*t10);
d100 = sin(2*pi*0.23 .*t100)+cos(2*pi*12 .*t100);
As it is the same surface that I measure but with different spatial resolution, i.e. different sampling period, the single-sided Amplitude spectrum of these rugosity profiles should overlap, shouldn't they?
Unlike what I should obtain, I have the following graphs: and
Using the following function:
function [f,P1,S1] = FFT_PowerSpectrumDensity(time,signal,flagfig)
H=signal;
X=time;
ell=length(X);
L = ell;% 2^(nextpow2(ell)-1) % Next power of 2 from length of the signal
deltaTime = mean(diff(X));
Fs=1/deltaTime; %% mean sampling frequency
%% Compute the Fourier transform of the signal.
Y = fft(H);
%% Compute the two-sided spectrum P2. Then compute the single-sided spectrum P1 based on P2 and the even-valued signal length L.
P2 = abs(Y/L); % abs(fft(signal Y)) / Length_of_signal
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(L/2))/L;
if flagfig~=0
figure(flagfig)
loglog(f,P1)
title('Single-Sided Amplitude Spectrum of X(t)','FontSize',18)
xlabel('Spatial frequency f=1/\lambda (m^{-1})','FontSize',14)
ylabel('|P1(f)| (m)','FontSize',14)
end
S = (Y.*conj(Y)).*(2/L).^2; % power spectral density
S1 = S(1:L/2+1);
S1(2:end-1) = S1(2:end-1);
%% Power spectrum (amplitude = a^2+b^2), in length^2
if flagfig~=0
figure(flagfig+1)
loglog(f,S1)
title('Power spectrum','FontSize',18)
xlabel('Spatial frequency f=1/\lambda (m^{-1})','FontSize',14)
ylabel('(Y*2/L)^2 (m^2)','FontSize',14)
end
end
I call this function for instance using the following command:
[f10, S10]= FFT_PowerSpectrumDensity(t10, d10, 10);
Should I use L=2^pow2(ell)-1)
? I understood that it provides a better input to the FFT function? Also, I am quite unsure about most of the units and values I should find.
Thank you for your help, corrections and suggestions.
Upvotes: 2
Views: 351
Reputation: 60444
Your problem is in your input signal:
N=512;
t100 = linspace(0,100, N);
d100 = sin(2*pi*0.23 .*t100)+cos(2*pi*12 .*t100);
d100
is undersampled. You have cos(0)
in your fist sample, then cos(2*pi*12*0.1953
= cos(2*pi*2.3436)
in your second sample. That is 2.3 periods later!
Plotting d100
and d10
together, and zooming in on the first 10 s of the signal, reveals the issue:
Consequently, the lower frequency component is estimated correctly (the broad peak for d10
is due to few periods and not an integer number of them), but the higher frequency component, aliased for d100
, appears at a lower frequency.
BTW: Regarding changing the transform length to a power of two: this will speed up computation in general, but in this case you already have a power of two length signal. The results will not be better, it is just about computation speed.
Upvotes: 1