I want to do fft analysis of the input signal but I am getting the following error

2 views (last 30 days)
Karthik B K
Karthik B K on 30 Nov 2021
Commented: Karthik B K on 6 Dec 2021
%Clear command window, variables and close all open figures (if any)
clc;
clear all;
% close all;
%Import the CSV file
filename = '2DOF_11a.csv';
opts = detectImportOptions(filename,'NumHeaderLines',0); % number of header lines which are to be ignored
opts.VariableNamesLine = 0; % row number which has variable names
opts.DataLine = 1; % row number from which the actual data starts
tbl = readtable(filename,opts);
% Time (numerical)
time = table2array(tbl(:,1));
Fs = 1/time(2); % Sampling frequency
%x1 (numerical)
x1_num = table2array(tbl(:,2));
%x2 (numerical)
% x2_num = table2array(tbl(:,5));
%
% %x1 (analytical)
% x1_ana = table2array(tbl(:,8));
% %x2 (analytical)
% x2_ana = table2array(tbl(:,11));
% % x2_ana = str2double(x2_ana); %x2_ana was coming as a cell in the line before, so had to add this line
%
L = length(x1_num); %Length of all the signals
% %
% % % PSD of x1 (numerical) using Hanning window
% % % F is the set of actual frequencies (will be same for all signals)
[PSD_x1_num,F] = periodogram(x1_num, hanning(L), L, Fs, 'power');
%
% % PSD of x2 (numerical) using Hanning window
% PSD_x2_num = periodogram(x2_num, hanning(L), L, Fs, 'power');
%
% % PSD of x1 (analytical) using Hanning window
% PSD_x1_ana = periodogram(x1_ana, hanning(L), L, Fs, 'power');
%
% % PSD of x2 (analtical) using Hanning window
% PSD_x2_ana = periodogram(x2_ana, hanning(L), L, Fs, 'power');
%
f_index = find(F >= 10);
F_set = 1:f_index(1); %Frequency index to plot is between 0 to 10 Hz
% %
figure(1);
clf;
% % Plot x1 PSDs
plot(F(F_set),PSD_x1_num(F_set),'b','linewidth',2.0);
hold on;
plot(F(F_set),PSD_x1_ana(F_set),'r--','linewidth',2.0);
xlabel('Frequency (Hz)')
ylabel('PSD')
%
% figure(2);
% clf;
% % Plot x2 PSDs
% % plot(F(F_set),PSD_x2_num(F_set),'b','linewidth',2.0);
% hold on;
% plot(F(F_set),PSD_x2_ana(F_set),'r--','linewidth',2.0);
% xlabel('Frequency (Hz)')
% ylabel('PSD')
% %
freq = [F(F_set) PSD_x1_num(F_set)]; %PSD_x1_ana(F_set) PSD_x2_num(F_set) PSD_x2_ana(F_set)];
I am getting the following error
Error in periodogram (line 215)
[Sxx,w2,RSxx,wc] = computeperiodogram(x,win,nfft,esttype,Fs,options);
Error in fft_SV (line 34)
[PSD_x1_num,F] = periodogram(x1_num, hanning(L), L, Fs, 'power');

Answers (2)


Mathieu NOE
Mathieu NOE on 3 Dec 2021
hello
I had to tweak a bit my code because your data file does not have same amount of rows depending at which column we look at
now, I don't know which of the data is interesting for you, but basically I found only 2 could be of some interest
select the channel you want to process using this line
selected_channel = 2; % 2,4 or 5 , 3 is empty
full code :
clc
clearvars
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% load signal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% data
% data has 2 columns (time / signal)
data = table2array(readtable('2DOF_1a.csv'));
time = data(:,1);
signal = data(:,2:end);
[samples,channels] = size(signal);
% select one channel and remove NaN if needed
selected_channel = 2; % 2,4 or 5 , 3 is empty
signal = data(:,selected_channel);
ind = find(~isnan(signal));
signal = signal(ind);
time = time(ind);
Fs = 1/mean(diff(time));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% FFT parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
NFFT = 256; %
OVERLAP = 0.95;
% spectrogram dB scale
spectrogram_dB_scale = 80; % dB range scale (means , the lowest displayed level is XX dB below the max level)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% options
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% if you are dealing with acoustics, you may wish to have A weighted
% spectrums
% option_w = 0 : linear spectrum (no weighting dB (L) )
% option_w = 1 : A weighted spectrum (dB (A) )
option_w = 0;
%% decimate (if needed)
% NB : decim = 1 will do nothing (output = input)
decim = 1;
if decim>1
for ck = 1:channels
newsignal(:,ck) = decimate(signal(:,ck),decim);
Fs = Fs/decim;
end
signal = newsignal;
end
samples = length(signal);
time = (0:samples-1)*1/Fs;
%%%%%% legend structure %%%%%%%%
for ck = 1:channels
leg_str{ck} = ['Channel ' num2str(ck) ];
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display 1 : time domain plot
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
figure(1),plot(time,signal);grid on
title(['Time plot / Fs = ' num2str(Fs) ' Hz ']);
xlabel('Time (s)');ylabel('Amplitude');
legend(leg_str);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display 2 : averaged FFT spectrum
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[freq, sensor_spectrum] = myfft_peak(signal,Fs,NFFT,OVERLAP);
% convert to dB scale (ref = 1)
sensor_spectrum_dB = 20*log10(sensor_spectrum);
% apply A weigthing if needed
if option_w == 1
pondA_dB = pondA_function(freq);
sensor_spectrum_dB = sensor_spectrum_dB+pondA_dB;
my_ylabel = ('Amplitude (dB (A))');
else
my_ylabel = ('Amplitude (dB (L))');
end
figure(2),plot(freq,sensor_spectrum_dB);grid on
df = freq(2)-freq(1); % frequency resolution
title(['Averaged FFT Spectrum / Fs = ' num2str(Fs) ' Hz / Delta f = ' num2str(df,3) ' Hz ']);
xlabel('Frequency (Hz)');ylabel(my_ylabel);
legend(leg_str);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display 3 : time / frequency analysis : spectrogram demo
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for ck = 1:channels
[sg,fsg,tsg] = specgram(signal(:,ck),NFFT,Fs,hanning(NFFT),floor(NFFT*OVERLAP));
% FFT normalisation and conversion amplitude from linear to dB (peak)
sg_dBpeak = 20*log10(abs(sg))+20*log10(2/length(fsg)); % NB : X=fft(x.*hanning(N))*4/N; % hanning only
% apply A weigthing if needed
if option_w == 1
pondA_dB = pondA_function(fsg);
sg_dBpeak = sg_dBpeak+(pondA_dB*ones(1,size(sg_dBpeak,2)));
my_title = ('Spectrogram (dB (A))');
else
my_title = ('Spectrogram (dB (L))');
end
% saturation of the dB range :
% saturation_dB = 60; % dB range scale (means , the lowest displayed level is XX dB below the max level)
min_disp_dB = round(max(max(sg_dBpeak))) - spectrogram_dB_scale;
sg_dBpeak(sg_dBpeak<min_disp_dB) = min_disp_dB;
% plots spectrogram
figure(2+ck);
imagesc(tsg,fsg,sg_dBpeak);colormap('jet');
axis('xy');colorbar('vert');grid on
df = fsg(2)-fsg(1); % freq resolution
title([my_title ' / Fs = ' num2str(Fs) ' Hz / Delta f = ' num2str(df,3) ' Hz / Channel : ' num2str(ck)]);
xlabel('Time (s)');ylabel('Frequency (Hz)');
end
function pondA_dB = pondA_function(f)
% dB (A) weighting curve
n = ((12200^2*f.^4)./((f.^2+20.6^2).*(f.^2+12200^2).*sqrt(f.^2+107.7^2).*sqrt(f.^2+737.9^2)));
r = ((12200^2*1000.^4)./((1000.^2+20.6^2).*(1000.^2+12200^2).*sqrt(1000.^2+107.7^2).*sqrt(1000.^2+737.9^2))) * ones(size(f));
pondA = n./r;
pondA_dB = 20*log10(pondA(:));
end
function [freq_vector,fft_spectrum] = myfft_peak(signal, Fs, nfft, Overlap)
% FFT peak spectrum of signal (example sinus amplitude 1 = 0 dB after fft).
% Linear averaging
% signal - input signal,
% Fs - Sampling frequency (Hz).
% nfft - FFT window size
% Overlap - buffer percentage of overlap % (between 0 and 0.95)
[samples,channels] = size(signal);
% fill signal with zeros if its length is lower than nfft
if samples<nfft
s_tmp = zeros(nfft,channels);
s_tmp((1:samples),:) = signal;
signal = s_tmp;
samples = nfft;
end
% window : hanning
window = hanning(nfft);
window = window(:);
% compute fft with overlap
offset = fix((1-Overlap)*nfft);
spectnum = 1+ fix((samples-nfft)/offset); % Number of windows
% % for info is equivalent to :
% noverlap = Overlap*nfft;
% spectnum = fix((samples-noverlap)/(nfft-noverlap)); % Number of windows
% main loop
fft_spectrum = 0;
for i=1:spectnum
start = (i-1)*offset;
sw = signal((1+start):(start+nfft),:).*(window*ones(1,channels));
fft_spectrum = fft_spectrum + (abs(fft(sw))*4/nfft); % X=fft(x.*hanning(N))*4/N; % hanning only
end
fft_spectrum = fft_spectrum/spectnum; % to do linear averaging scaling
% one sidded fft spectrum % Select first half
if rem(nfft,2) % nfft odd
select = (1:(nfft+1)/2)';
else
select = (1:nfft/2+1)';
end
fft_spectrum = fft_spectrum(select,:);
freq_vector = (select - 1)*Fs/nfft;
end
  1 Comment
Karthik B K
Karthik B K on 6 Dec 2021
Firstly, thank you for helping.
Actually I need to do FFT analysis for the input signal which is in second(Column B) column. The first column indicates time span of the complete signal. In the code, I have commented for the remaining column. The same code is used for the different problem which had number of input signal. But if I use the same code for this probem I am getting the above mentioned errors.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by