Matlab power spectrum analysis - matlab

I would like to reproduce this image, but with my own EEG data.
For what I understand, it is a power spectrum analysis done on filtered data.
I recorded the EEG signal with a sampling rate of 1000Hz, with DC amplifiers (Low: DC; High:200). My Data is: 68 (electrodes) x 185080 (data points).
I have tried to use the following code from:http://uk.mathworks.com/help/signal/ug/psd-estimate-using-fft.html
Fs = 1000;
t = 0:1/Fs:1-1/Fs;
x = Data;
%x = cos(2*pi*100*t) + randn(size(t));
N = length(x);
xdft = fft(x);
xdft = xdft(1:N/2+1);
psdx = (1/(Fs*N)) * abs(xdft).^2;
psdx(2:end-1) = 2*psdx(2:end-1);
freq = 0:Fs/length(x):Fs/2;
plot(freq,10*log10(psdx))
grid on
title('Periodogram Using FFT')
xlabel('Frequency (Hz)')
ylabel('Power/Frequency (dB/Hz)')
but this is what I obtain:
I am struggling understanding how to proceed in order to obtain an analysis of my EEG signal as in the first image. Any help would be very much appreciated.

Here's a simple example of how to do PSD using fft from scratch and without the DSP toolbox:
%this does not include any filtering
x = [0:0.01:pi];
y = sin(100*x);
nfft = 2^nextpow2(length(y));
Fs = 100;
psd1 = abs(fft(y,nfft)).^2/length(y)/Fs;%compute the PSD and normalize
plot([0:50/(length(psd1)/2):50],psd1(1:length(psd1)/2+1))
xlabel('Frequency (Hz)');
ylabel('PSD');
grid on
title('PSD from FFT');
The result:
If this method results in a similar one to what you posted then I think the other's comments about your data having some issues may be valid.

Related

Optical frequency comb time to frequency domain - MATLAB

I am trying to generate ultrashort pulses and then seeing the resulting frequency comb using a fourier transform, I have used the gaussian pulse and pulse train functions to try and do this but it is not coming out correctly - I am hoping to be able to change the variables at the top to see the changes quickly
If here is a solution or any good resources that could help me I would appreciate it alot... Thanks
Code is here:
fs = 1e17 ; % sample rate
frep = 7.5e9; % repition rate
f_sig = 1.93e15; %frequency of signal
tc = gauspuls('cutoff',f_sig,100,[],-80);
t = -tc*200:1/fs:tc*200;
[x1,x2,x3] = gauspuls(t,f_sig,0.5);
figure(1);
plot(t,x1,t,x3)
xlabel('Time (s)')
ylabel('Waveform')
ts = 0:1/fs/2:tc*50000000 ;
d = 0:1/frep:tc*50000000 ; %delay
y = pulstran(ts,d,x,fs);
figure(2);
plot(ts,y)
%Frequency Comb FFT
fsamp = fs;
L= length(t); %signal length
NFFT = 2^nextpow2(L);
FFT = abs(fftshift(fft(x3,NFFT))/NFFT); %FFT with FFTshift for both negative & positive frequencies
f = fsamp*(-NFFT/2:(NFFT/2-1))/NFFT; %Frequency Vector
figure(3)
plot(f/1e9,10*log10(FFT/1e-3));
title('Magnitude of FFT');
xlabel('Frequency (GHz)');
ylabel('Magnitude |X(f)|');
%xlim([-100 100])

MATLAB FFT waveform plot with detrend and shift only has one spike

I have some beginner, basic Physionet data I am trying to apply FFT to, but I'm a bit confused by the results I'm getting and don't think they're correct. I'm mostly using code from this example and from the fftshift documentation page with some tweaks but I'm not too sure what's wrong with my code or results. I have attached my code and snapshots of the results I'm getting.
load aami3am.mat
Fs = 720; % Sampling frequency
T = 1/Fs; % Sample time
L = 60000; % Length of signal
t = (0:L-1)*T; % Time vector
plot(t(1:43081),val(1:43081))
title('aami4b_h Signal')
xlabel('Seconds')
ylabel('ECG Amplitude')
NFFT = 2^nextpow2(L);
val = detrend(val);
Y = fft(val,NFFT)/L;
f = Fs/2*linspace(0,1,NFFT/2+1);
plot(f,2*abs(Y(1:NFFT/2+1)))
title('FFT')
yY = fftshift(Y);
fshift = (-L/2:L/2-1)*(Fs/L);
powershift = abs(yY).^2/L;
plot(fshift(1:L),powershift(1:L))
title('FFT Shifted')
I'm using 43081 because there are 43081 values in the .mat file over the 60 seconds of data.

From time domaine to frequency domain

I have a problem in my MATLAB program. I'm trying to find a cutoff frequency to create a low pass filter for compass data. I'm trying to go from the time domain to the frequency domain and find an Fc, so I used the FFT but it seems that's it's nor working.
This is what i have done:
dataset=xlsread('data.xlsx','Feuil1','A1:A751');
t=1:length(dataset);
z=abs(fft(dataset));
subplot(2,2,3)
plot(dataset)
title('dataNonFiltrer')
subplot(2,2,4)
plot(z)
title('frequenciel')
And i get this wish seems to be not correct:
You are just not plotting the data right.
To plot the fft of a signal X, do (from the docs):
Fs = 1000; % Sampling frequency of your data. YOU NEED TO KNOW THIS, change
L = length(X); % Length of signal
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;
plot(f,P1)
title('frequenciel X(t)')
xlabel('f (Hz)')
ylabel('|P1(f)|')

Plotting FFT fails due to vectors not having the same length

I have a csv data of time(1st column) and current amplitude(2nd column). I want to plot FFT of the current. This is actually simulation data over 30ns and data step was 1ps. I can plot the current vs Time in MATLAB. But while doing FFT function, It is not plotting at all as it says
Error using plot
Vectors must be the same length.
Error in FFT_Ideal_current_maxstep_1ps (line 25).
plot(f,Y)
Can anyone help me? I have attached the MATLAB code and the CSV file as well.
I also want to plot the power spectral density. It would be nice if anyone can help. I want to get the FFT and psd over 2GHz or more frequency spectrum range
MATLAB code1:
% open data file
fid = fopen('current_maxstep_1ps.csv');
% Read data in from csv file
readData = textscan(fid,'%f %f','Headerlines',1,'Delimiter',',');
% Extract data from readData
t = readData{1,1}(:,1);
x = readData{1,2}(:,1);
N = length(x);
ts = 0.000000000001;
Fs = 1/ts;
tmax = (N-1)*ts;
tm = 0:ts:tmax;
f = 0:Fs/(N-1):Fs/2;
y = fftshift(fft(x));
Y = abs(y);
plot(f,Y)
Also there is another MATLAB code I tried which plots (here is the picture: FFT picture of code 2) but showing in time domain and I want frequency spectrum like spikes of apmlitudes along the frequency spectrum.
MATLAB Code2:
% open data file
fid = fopen('Ideal_current_maxstep_1ps.csv');
% Read data in from csv file
readData = textscan(fid,'%f %f','Headerlines',1,'Delimiter',',');
% Extract data from readData
xData = readData{1,1}(:,1);
yData = readData{1,2}(:,1);
Ts = 1e-12;
Fs = 1/Ts;
%Fs = 1000;
%Ts = 1/Fs;
X = fft(yData);
plot(xData, abs(X))
The problem is that the length of f and Y are not the same. You can check it using length(f) and length(Y). The reason is that fft also calculates the negative frequencies. Therefore, you should define f as follows:
f = -Fs/2:Fs/(N-1):Fs/2;
Note that the fft is conjugate symmetric, because the input data is real.
You can limit the plotted frequency range using the xlim command as follows:
xlim([0 3*10^9]) % limit x range between 0Hz and 3GHz

DFT code on Matlab does not work as intended

I am trying to implement a basic DFT algorithm on Matlab.
I simply use in phase and quadrature components of a sine wave with phase modulation(increasing frequency a.k.a chirp). I do compare my results with fft command of Matlab. My code gives the same results whenever there is no phase modulation(pure sine). Whenever I add chirp modulation, results differ. For example, when I use a chirp with some bandwidth around a carrier, the expected results should be a frequency distribution of chirp bandwidth starting from carrier frequency. However, I get a copy of that result backwards starting from carrier frequency as well. You can use my code below without modifying anything. Figure 5 is my result and figure 6 is the expected result. Carrier is 256 Hz with a 10Hz bandwidth of chirp. You can see the code below. The important part is for loop where I take dft of my signal. Also uou can see my dft result below.
close all;
clear all;
%% signal generation
t = (0:0.0001:1); % 1 second window
f = 256; %freq of input signal in hertz
bw = 10; % bandwidth sweep of signal
phaseInput = 2*pi*t*bw.*t;
signalInput = sin(2*pi*f*t + phaseInput); %input signal
inphase = sin(2*pi*f*t).*cos(phaseInput); %inphase component
quadrature = cos(2*pi*f*t).*sin(phaseInput); %quadrature component
figure
plot(t,signalInput,'b',t,inphase,'g',t,quadrature,'r');
title('Input Signal');
xlabel('Time in seconds');
ylabel('Amplitude');
%% sampling signal previously generated
Fs = 1024; %sampling freq
Ts = (0:1/Fs:1);%sample times for 1 second window
sPhase = 2*pi*Ts*bw.*Ts;
sI = sin(2*pi*f*Ts).*cos(sPhase);
sQ = cos(2*pi*f*Ts).*sin(sPhase);
hold on;
plot(Ts,sI+sQ,'b*',Ts,sI,'g*',Ts,sQ,'r*');
fftSize = Fs; %Using all samples in dft
sampleIdx = (0:1:fftSize-1)';
sampledI = sI(1:fftSize)';
sampledQ = sQ(1:fftSize)';
figure;
plot(sampleIdx,sampledI,sampleIdx,sampledQ);
title('Sampled IQ Components');
%% DFT Calculation
dftI = zeros(fftSize,1);
dftQ = zeros(fftSize,1);
for w = 0:fftSize-1
%exp(-2*pi*w*t) = cos(2*pi*w*t) - i*sin(2*pi*w*t)
cI = cos(2*pi*w*sampleIdx/fftSize); %correlation cos
cQ = -sin(2*pi*w*sampleIdx/fftSize); %correlation sin
dftI(w+1) = sum(sampledI.*cI - sampledQ.*cQ); %
dftQ(w+1) = sum(sampledI.*cQ + sampledQ.*cI);
end;
figure;
plot(Fs*sampleIdx/fftSize,dftI);
title('DFT Inphase');
xlabel('Hertz');
figure
plot(Fs*sampleIdx/fftSize,dftQ);
title('DFT Quadrature');
xlabel('Hertz');
figure;
plot(Fs*sampleIdx/fftSize,sqrt(dftQ.^2+dftI.^2));
%% For comparison
sampledInput = sin(2*pi*f*Ts + sPhase);
Y = fft(sampledInput(1:1024),1024);
Pyy = Y.*conj(Y)/1024;
f = (0:1023);
figure;
plot(f,Pyy)
title('Power spectral density')
xlabel('Frequency (Hz)')
the reason lies in the fact that two different signals will definitely give your two different frequency spectrums. check out the code below, you will find that the input of the dft algorithm you actually gave is sampledI+jsampledQ. as a result, what you are doing here is NOT merely decomposing your original signal into In-phase and quadrature components, instead, you are doing Hilbert transform here -- to change a real signal into a complex one.
cI = cos(2*pi*w*sampleIdx/fftSize); %correlation cos
cQ = -sin(2*pi*w*sampleIdx/fftSize); %correlation sin
dftI(w+1) = sum(sampledI.*cI - sampledQ.*cQ); %
dftQ(w+1) = sum(sampledI.*cQ + sampledQ.*cI);
so the sampledInput for comparison should be sampledInput = sI+1i*sQ;.