Determining the phase response of a PRBS 7 signal in MATLAB - matlab

I have taken a 32Gbps NRZ signal measurement using a real time oscilloscope. I have the time and values in 2 different columns (time domain data). I have imported the 2 values to two different arrays in Matlab (NRZ_time, NRZ_values).
Now, I want to compute the FFT of the signal. I know it can be done like this.
NRZ_fft = fft(NRZ_values);
Then, I want to plot the magnitude and phase response which I am doing with
figure;
plot(abs(NRZ_fft));
figure;
plot(angle(NRZ_fft));
I am sure the magnitude response is correct but the phase response is wrong according to me. Can someone confirm, I am doing it right or not?
Also I want to find the sampling frequency from this data. There are 65521 samples. The first value in the time column is -0.0000000166801500 and the last value is 0.0000000345073500. So, the length of the signal is:
0.0000000345073500 - (-0.0000000166801500) = 5.1187e-008.
How do I calculate the sampling frequency from this data?

Related

Convert frequency Domain data of transducer to time Domain Transfer Function

I have a few .mat files that denote the characteristics of a transducer (transmitter); I want to use the data for my Matlab code, in order to observe the response it will have on my transmit signal.
The first file contains Magnitude of the transducer as follows: Each row contains the frequency response for one angle. Each column contains the angular response at one frequency.
Similarly, I have another .mat file that contains corresponding phase (in degrees) of the transmit voltage response
The frequencies (in Hz) (corresponding to the rows) are in another matrix given by a third .mat file
and similarly, The angles (in deg) (corresponding to the columns) are in another matrix given by a 4th file.
Can someone help me translate these into a Time Domain representation for a specific angle (using the Magnitude and phase information for a specific angle) and construct a Transfer Function to be used???
Any help will be appreciated.
In order to convert responses from the frequency domain into the time domain, you need to perform an inverse Fourier transformation. In matlab, this is done with the function ifft.
Lets consider that you load the data from the first file into the variable magnitude and from the second file into variable phase. You have to first merge these two variables into a single complex valued matrix
f_response = complex(magnitude.*cosd(phase),magnitude.*sind(phase));
The f_response is the actual response of your transducer, and can be supplied to ifft in order to get the time domain response. However there is a complication, the assumed frequency order implied by ifft. Although matlab does not provide much details about this, if you check out the fft docs, you will see that there are two frequency branches returned by fft. The frequency responses must be ordered in a way that corresponds to matlab's expected order. If you take, for instance, the first example in the docs
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sampling period
L = 1000; % 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 + 2*randn(size(t));
Y = fft(X);
The frequency array that corresponds to each of the Fourier transform output Y entries is:
f = Fs/L*[0:(L/2-1),-L/2:-1];
In order to correctly apply the Fourier inverse transformation, you have to check if the order in your frequencies file (lets assume you loaded its contents to the variable frequencies) has to be ordered exactly like f. Note that f has a regular increasing first branch and then makes a discontinuous jump to negative frequencies. The sign of the frequencies is used to represent the propagation direction of travelling waves. If your data only holds positive frequencies, that would be excellent because you would be able to construct the negative frequency branch easily as:
[frequencies,ix] = sort(frequencies);
f_response = f_response(:,ix);
f_response = 0.5*[f_response(:,1:end-1),f_response(:,end:-1:2)];
and then invert it by doing
t_response = ifft(f_response,[],1);
Note that, as you want the response for each angle, each row must be inverse transformed. This is achieved with the third input to ifft.
If your frequencies data file has negative frequencies, then you have to order it correctly and then re-order the f_response columns accordingly. You would need to upload some sample data for me to be able to help more with that.

how to use ifft function in MATLAB with experimental data

I am trying to use the ifft function in MATLAB on some experimental data, but I don't get the expected results.
I have frequency data of a logarithmic sine sweep excitation, therefore I know the amplitude [g's], the frequency [Hz] and the phase (which is 0 since the point is a piloting point).
I tried to feed it directly to the ifft function, but I get a complex number as a result (and I expected a real result since it is a time signal). I thought the problem could be that the signal is not symmetric, therefore I computed the symmetric part in this way (in a 'for' loop)
x(i) = conj(x(mod(N-i+1,N)+1))
and I added it at the end of the amplitude vector.
new_amp = [amplitude x];
In this way the new amplitude vector is symmetric, but now I also doubled the dimension of that vector and this means I have to double the dimension of the frequency vector also.
Anyway, I fed the new amplitude vector to the ifft but still I don't get the logarithmic sine sweep, although this time the output is real as expected.
To compute the time [s] for the plot I used the following formula:
t = 60*3.33*log10(f/f(1))/(sweep rate)
What am I doing wrong?
Thank you in advance
If you want to create identical time domain signal from specified frequency values you should take into account lots of details. It seems to me very complicated problem and I think it need very strength background on the mathematics behind it.
But I think you may work on some details to get more acceptable result:
1- Time vector should be equally spaced based on sampling from frequency steps and maximum.
t = 0:1/fs:N/fs;
where: *N* is the length of signal in frequency domain, and *fs* is twice the
highest frequency in frequency domain.
2- You should have some sort of logarithmic phases on the frequency bins I think.
3- Your signal in frequency domain must be even to have real signal in time domain.
I hope this could help, even for someone to improve it.

Plotting time vs frequency in matlab

I am trying to find a way to create a graph that shows an audio wave and its time-frequency data (time on x-axis, wave energy and frequency data on y-axis). I have this code that does it on two separate plots:
[audio, fs] = wavread('audio.wav');
subplot(211)
spectrogram(audio,256,200,256,fs,'yaxis')
subplot(212)
wavEnergy=audio(:,1);
time=(1/fs)*length(wavEnergy);
t=linspace(0,time,length(wavEnergy));
plot(t,wavEnergy);
and now I need help with 2 things.
First, how do I get the spectrogram time to be in terms of seconds? Right now it graphs with an x-range of 0-340 (labeled 'time') and I know the clip is about 40s long (the other plot properly displays this).
Second, how do I plot them together? I know I can get a matrix from spectrogram but which array do I get from that matrix and how do I convert its timeframe to seconds?
EDIT:
First problem solved, but the graphs are still doing something strange - they both output about 40s of data, but the ranges of the graphs and the offsets of the data are different. The spectrogram goes from 0s-40s but the first .5s shows no data, and the wave plot goes from 0s-45s and the last 5s shows no data. How can I get the ranges and offsets to be the same?
EDIT 2:
I just needed to use axis tight; on both subplots
Aligning these two plots on the same time-base relies on determining the sampling frequency of your data. Based on the parameter you are passing to spectrogram, the sampling frequency is 1000 Hz. Based on your definition of time = (1/8000)*length(wavEnergy), the sampling frequency is 8000 Hz. These are not consistent. To get the audio sampling frequency from your wav file you can use [audio, fs] = wavread('audio.wav').

Complex FFT then Inverse FFT MATLAB

I am using the FFT function in Matlab in an attempt to analyze the output of a Travelling Wave Laser Model.
The of the model is in the time domain in the form (real, imaginary), with the idea being to apply the FFT to the complex output, to obtain phase and amplitude information in the frequency domain:
%load time_domain field data
data = load('fft_data.asc');
% Calc total energy in the time domain
N = size(data,1);
dt = data(2,1) - data (1,1);
field_td = complex (data(:,4), data(:,5));
wavelength = 1550e-9;
df = 1/N/dt;
frequency = (1:N)*df;
dl = wavelength^2/3e8/N/dt;
lambda = -(1:N)*dl +wavelength + N*dl/2;
%Calc FFT
FT = fft(field_td);
FT = fftshift(FT);
counter=1;
phase=angle(FT);
amptry=abs(FT);
unwraptry=unwrap(phase);
Following the unwrapping, a best fit was applied to the phase in the region of interest, and then subtracted from the phase itself in an attempt to remove wavelength dependence of phase in the region of interest.
for i=1:N % correct phase and produce new IFFT input
bestfit(i)=1.679*(10^10)*lambda(i)-26160;
correctedphase(i)=unwraptry(i)-bestfit(i);
ReverseFFTinput(i)= complex(amptry(i)*cos(correctedphase(i)),amptry(i)*sin(correctedphase(i)));
end
Having performed the best fit manually, I now have the Inverse FFT input as shown above.
pleasework=ifft(ReverseFFTinput);
from which I can now extract the phase and amplitude information in the time domain:
newphasetime=angle(pleasework);
newamplitude=abs(pleasework);
However, although the output for the phase is greatly different compared to the input in the time domain
the amplitude of the corrected data seems to have varied little (if at all!),
despite the scaling of the phase. Physically speaking this does not seem correct, as my understanding is that removing wavelength dependence of phase should 'compress' the pulsed input i.e shorten pulse width but heighten peak.
My main question is whether I have failed to use the inverse FFT correctly, or the forward FFT or both, or is this something like a windowing or normalization issue?
Sorry for the long winded question! And thanks in advance.
You're actually seeing two effects.
First the expected one goes. You're talking about "removing wavelength dependence of phase". If you did exactly that - zeroed out the phase completely - you would actually get a slightly compressed peak.
What you actually do is that you add a linear function to the phase. This does not compress anything; it is a well-known transformation that is equivalent to shifting the peaks in time domain. Just a textbook property of the Fourier transform.
Then goes the unintended one. You convert the spectrum obtained with fft with fftshift for better display. Thus before using ifft to convert it back you need to apply ifftshift first. As you don't, the spectrum is effectively shifted in frequency domain. This results in your time domain phase being added a linear function of time, so the difference between the adjacent points which used to be near zero is now about pi.

FFT when data set has varying vector lengths

I have data from a model I am running. However the data is collected at each time step and there are varying numbers of time steps. It works out that although there are varying time steps, it is compensated by the change in time step so that all runs are running for the same time.
However I would think that when I have a vector that is 200 in length and one that is 900 in length, taking the FFT will give me inherently different frequencies. I feel like I should take the FFT with respect to the same time axis of all the samples.
The way I have the data now is just as row vectors were each entry is not associated with a space in time.
Is there a way to take the fft of each vector with respect to their place in a time axis rather than their place in the vector array?
My goal is to write a for loop and take the fft of many data sets, and then plot them to compare of frequency signatures change.
If you collect 200 samples in 1 second (200 Hz), you can resolve input data from 1 Hz (1/(1 sec)) to 100 Hz. If you sample for 1 second collecting 900 samples, you can resolve input from 1 Hz to 450 Hz. So both your samples have the same spacing (sampling in the frequency axis is 1 Hz), but they go up to different maximum frequencies!
If your issue is just about plotting, you can either throw away the high frequencies which are not available in all your plots:
totaltime=1; %# common total time of all datasets, in seconds
minsamplenumber=200;
figure;
hold all;
cutofffreq=((minsamplenumber/2+1)/totaltime);
freqscale=0:(1/totaltime):cutofffreq;
datasetcount=42;
ffts=NaN(minsamplenumber,datasetcount);
for i=1:datasetcount
data{i}=... %# collect your data; to make life easier always collect an even number..
ffts(:,i)=fft(data{i},minsamplenumber);
plot(freqscale,ffts{i}(1:end/2+1));
end
... or live with reality, and plot all data you have:
totaltime=1; %# common total time of all datasets, in seconds
figure;
hold all;
for i=1:42
data{i}=... %# collect your data; to make life easier always collect an even number..
ffts{i}=fft(data{i});
maxfreq(i)=((numel(ffts{i})/2+1)/totaltime);
freqscale{i}=0:(1/totaltime):maxfreq(i);
plot(freqscale{i},ffts{i}(1:end/2+1));
end
You could resample your data (by filtered interpolation) into constant length vectors where the sample rate was the same constant rate in each frame. You may have to overlap your FFT frames as well to get constant frame or window offsets.