Window gain factor in FFT
Show older comments
I have some vibration data (acceleration) on whcih I need to perform an FFT, and then integrate it and again do an FFT.
I read for the nature of the data that I have, the input to the FFT must be sent throgh the Hann window (or Hanning) in order to avoid spectral leakage in the frequency domain representation after I perform the FFT. I further read that the amplitude of the FFT output vector must be corrected, becasue of the window function's 'window gain factor'.
The said window gain factor for the Hann window is about 0.5 and that means I must multiply the real part of each entry in the output array with 2 to effect this correction. My expectation was - If I DO NOT perform the window gain correction, the amplitudes on the Y axis of my FFTs will be about half the magnitude as that of the rectangular window, and therefore the correction is called for.
However, when I use 3 different window functions - Rectangular, Hanning and Flat-Top - WITHOUT performing any corrections for the gain factor in any case, I still get the similar aplitudes on the Y axis of my FFT. (Refer pictures below - in each case the first graph is the FFT result of acceleration and the second graph is for speed).
A. Rectangular Windowing:

B. Hann Windowing:
C. Flat-top Windowing:

Why does this happen?
If I do perform the window gain correction, for example, in the case where I use the Hann window, then the amplitudes must be roughly double as compared to when I use a Rectangular window. How come that the amplitudes on the FFT results should be so wildly different if I use different window functions and do the correction correctly?
Should I ultimately do the correction for the window gain?
9 Comments
You didn't show us the code, but I find the expected result with the example code from fft doc without the random noise(*) with and without windowing --
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sampling period
L = 1500; % Length of signal
t = (0:L-1)*T; % Time vector
S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
X=S.';
Y = fft(X);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(L/2))/L;
subplot(3,1,1);
plot(f,P1,'k-','linewidth',2)
grid on
xlim([0 250]), ylim([0 1])
xlabel('Frequency'),ylabel('Amplitude')
title('No Windowing')
X=X.*hann(length(X),"periodic");
Y = fft(X);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
subplot(3,1,2);
plot(f,P1,'k-','linewidth',2)
grid on
xlim([0 250]), ylim([0 1])
xlabel('Frequency'),ylabel('Amplitude')
title('Hanning Window')
HannMean=mean(hann(length(X),"periodic"));
P1= P1/HannMean;
subplot(3,1,3);
plot(f,P1,'k-','linewidth',2)
xlim([0 250]), ylim([0 1])
grid on
xlabel('Frequency'),ylabel('Amplitude')
title('Hanning Window Normalized')
Would have to see just what you actually did to compensate but
HannMean
illustrates that the average window value is 0.5 as expected.
(*) Removing the random noise won't change the demonstration, just makes the output peak values identically equal to the input time series amplitudes for easy visualization. The random noise will cause small changes from being identically 0.7 and 1.0, but the result will still scale by exactly the factor of 2.
Chiranjeevi Viswa Teja Jupudi
on 7 Oct 2022
"... has a zero-padding step for the input singal to the next power of two (in this case, 2048). Of course, this step led the amplitudes on the FFTs to get reduced as comapred to when a non-padded signal was processed."
For proper energy conservation and normalization, if zero padding do NOT normalize by the full padded length but by the original sample length; there is no energy in the padding zeros so adding them into the divisor reduces the apparent signal strength by that ratio of L/N. This difference, of course, will be reduced in fractional size as the length of the sampled signal goes up.
The magnitude of the factor owing to the windowing is independent of the the data itself; as shown in the above example, both amplitudes are affected by the same magnitude indepedent of frequency.
The above is true for a stationary signal, the basic assumption underlying using the baseband FFT. Windowing is applied in the time domain; ergo, if the signal varies significantly over the sample window, the amplitude of the input (and hence the amplitude of the output containing the frequences in the portion of the sample window reduced) will be affected if the frequency content isn't the same across the time window as well.
Save one of your input traces as a .mat file and attach it...and the code that produced the above results; something's amiss it would seem; the length normalization would account for at least some of it.
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sampling period
L = 1500; % Length of signal
t = (0:L-1)*T; % Time vector
%S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
S=detrend(rand(size(t))); % use white noise to spread energy across spectrum
X=S.';
Y = fft(X);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(L/2))/L;
subplot(3,1,1);
plot(f,P1,'k-','linewidth',2)
grid on
xlim([0 250]), ylim([0 0.05])
xlabel('Frequency'),ylabel('Amplitude')
title('No Windowing')
X=X.*hann(length(X),"periodic");
Y = fft(X);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
subplot(3,1,2);
plot(f,P1,'k-','linewidth',2)
grid on
xlim([0 250]), ylim([0 0.05])
xlabel('Frequency'),ylabel('Amplitude')
title('Hanning Window')
HannMean=mean(hann(length(X),"periodic"));
P1= P1/HannMean;
subplot(3,1,3);
plot(f,P1,'k-','linewidth',2)
xlim([0 250]), ylim([0 0.05])
grid on
xlabel('Frequency'),ylabel('Amplitude')
title('Hanning Window Normalized')
Illustrates the effect is independent of frequency; but does show the broadening effect of the sidelobes in the window on amplitudes across the broad band for signals not precisely at a frequency bin midpoint.
The other thing that may be going on in your instance is that you're analyzing a transient signal -- in that case, applying any symmetric window such as Hanning, Hamming, etc., will greatly influence the overall magnitude and provide wrong results. NEVER apply such windowing to transient data. If this is the case, then you'll want to do "overlap" processing or analyze the whole transient without windowing -- the point of Hanning/Hamming/similar windowing is to remove the spurious transients that will be introduced analyzing a stationary time signal that is not sample such that an integral number of samples are taken. It (the window) artificially forces the time signal being analyzed to (or near) zero at both beginning and end to remove that discontinuity. That's not the situation with transient signals.
If you're measuring signals that also contain random noise besides any deterministic content, then you'll really need to average to reduce those effects; I posted an example of that recently as well...
It took a bunch of searching to remember a key word to find it, but the demo of averaging white noise repeated here is
a=2;
b=4;
t=1:1000; %time (10X the length of original -- dpb)
x=a*cos(2*pi*t/10); %signal without noise
xn=x+sqrt(b)*randn(size(x)); %signal with noise added
xn=reshape(xn,100,[]); % N traces of original length -- dpb
Xn=abs(fft(xn)); %abs(FFT) of xn
f=0:.01:.5; %vector of frequencies, up to Nyquist
%plot the results
subplot(211); plot(t,xn(:),'-rx');
xlabel('Time'); title('Time Domain');
subplot(212); plot(f,Xn(1:51,:)); % show the individual PSDs -- DPB
hold on
plot(f,mean(Xn(1:51,:),2),'k-','linewidth',2); % and the result of averaging
xlabel('Frequency'); title('Frequency Domain');
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sampling period
L = 1500; % Length of signal
t = (0:L-1)*T; % Time vector
N=2^nextpow2(L); % FFT length
S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
X=S.';
Y = fft(X,N);
P2 = abs(Y/L);
P1 = P2(1:N/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(N/2))/N;
hTL=tiledlayout(3,1);
hTL.Title.String="Padded FFT Normalization Using Signal Length, NOT Padded Length";
hTL.Title.FontSize=10.5; hTL.Title.FontWeight='bold';
nexttile
plot(f,P1,'k-','linewidth',2)
grid on
xlim([0 250]), ylim([0 1])
xlabel('Frequency'),ylabel('Amplitude')
title('No Windowing')
X=X.*hann(length(X),"periodic");
Y = fft(X,N);
P2 = abs(Y/L);
P1 = P2(1:N/2+1);
P1(2:end-1) = 2*P1(2:end-1);
nexttile
plot(f,P1,'k-','linewidth',2)
grid on
xlim([0 250]), ylim([0 1])
xlabel('Frequency'),ylabel('Amplitude')
title('Hanning Window')
HannMean=mean(hann(length(X),"periodic"));
P1= P1/HannMean;
nexttile
plot(f,P1,'k-','linewidth',2)
xlim([0 250]), ylim([0 1])
grid on
xlabel('Frequency'),ylabel('Amplitude')
title('Hanning Window Normalized')
Illustrates get the correct amplitude when normalize the FFT by only the actual signal length containing energy, NOT by the overall length of the zero-padded signal to increase FFT resolution.
Chiranjeevi Viswa Teja Jupudi
on 11 Oct 2022
dpb
on 11 Oct 2022
I think it would take having an intimate knowledge of the whole experiment/project to be able to comment intelligently on the analysis at any depth beyond just the basic things we've discussed that are purely mathematical properties of the computations undertaken.
From that viewpoint of a complete outsider looking in, I can think of only a couple general principles/techniques that I think would be paramount -- the first would be to use comparative samples in time of the two sensors; there may be, of course, a phase difference between the two owing to the comparative distance from the excitation source (but then again, of course, I have no idea what that may have been).
Secondly, if possible, still averaging of multiple instances may be the best noise reduction/"real" amplitude technique there is; particularly if this is an operating mechanism with a constant drive speed/load, etc,. ...
Alternatively, one may want to consider spectrographic methods with transient data to observe the time-varying aspects instead of treating the signal as the whole.
Mario Malic
on 12 Oct 2022
dpb
on 12 Oct 2022
BTW, one more thing just came to mind -- if, indeed, it is rotating machinery or some other sort of device with a repetitive nature; you may do well to consider triggered input on the input shaft or somesuch thing to begin the acquisition of each transient at the same point in the cycle.
Answers (0)
Categories
Find more on Multirate Signal Processing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!






