Calculate output of 2-port network, given an input pulse and S-parameters
8 views (last 30 days)
Show older comments
I am trying to calculate the output of a 2-port network, given an input pulse and S-parameters (exported from an antenna simulation in CST MWS). In the CST simulation environment I am able to see the output pulse, but when I calculate my output pulse, they differ greatly.
I start by converting the S-parameters to a voltage transfer function (in the frequency domain) by extracting the S21 parameter from the touchstone file. Next I take the inverse Fast Fourier transform of the transfer function and interpolate it to align it's time step with the input pulse. Finaly I convolve the input pulse with the transfer function (in time domain) to get the output pulse, but it does not resemble the simulated one.
My code is as follows:
%%Test for transforming S-param to transfer function
% Quinten Van den Brande
% IBCN+ - INTEC - EM group
clc;
clear all;
close all;
%%Read input files
% Input pulse
in = importdata('INPUT3.txt');
x1 = in.data(:,1).*1e-9;
y1 = in.data(:,2);
% Calculate signal properties
dt_in = x1(2,1); % time step ~ 0.0017 ns
tmax_in = x1(end,1); % signal duration
% Touchstone file '.s2p'
sparam = sparameters('air_fullmode_noeyelets_4.2GHz_closedwalls_32mmthick_optimized_construction_rotvar_0deg.s2p');
% sparam(1) = sparameters('air_fullmode_noeyelets_4.2GHz_closedwalls_32mmthick_optimized_construction_rotvar_0deg.s2p');
% sparam(2) = sparameters('air_fullmode_noeyelets_4.2GHz_closedwalls_32mmthick_optimized_construction_rotvar_15deg.s2p');
% sparam(3) = sparameters('air_fullmode_noeyelets_4.2GHz_closedwalls_32mmthick_optimized_construction_rotvar_30deg.s2p');
% sparam(4) = sparameters('air_fullmode_noeyelets_4.2GHz_closedwalls_32mmthick_optimized_construction_rotvar_45deg.s2p');
% sparam(5) = sparameters('air_fullmode_noeyelets_4.2GHz_closedwalls_32mmthick_optimized_construction_rotvar_60deg.s2p');
% rfplot(sparam);
%%Convert sparameters to voltage transfer function of the network
% http://nl.mathworks.com/help/rf/ug/s2tf.html
% Convert S21 to voltage transfer function
tf_f = s2tf(sparam);
% Calculate transfer function properties properties
df_tf = sparam.Frequencies(2)-sparam.Frequencies(1); % frequency resolution
N_tf = length(tf_f); % number of samples
Fs_tf = 2 * N_tf * df_tf; % sample frequency
dt_tf = 1/Fs_tf; % time step ~ 0.167 ns
% Convert frequency domain transfer function to time domain
tf = ifft(squeeze(sparam.Parameters(1,2,:)));
% Compensate time step difference between signal (td_in) and transfer function (td_tf)
tf = interp1(1:size(tf,1),tf,1:dt_in/dt_tf:N_tf, 'spline')';
figure;
plot((1:9000),real(tf(1:9000)), '-b','LineWidth', 1);
grid on;
xlabel('time [ns]','FontName','Times New Roman','fontsize',10);
ylabel('Input Pulse','FontName','Times New Roman','fontsize',10);
set(gca,'FontName','Times New Roman','FontSize',10);
%%Input pulse interpolation
x3 = (0:dt_in:tmax_in)';
y1 = interp1q(x1,y1,x3);
x1 = x3;
figure;
plot(x1,y1, '-b','LineWidth', 1);
grid on;
xlabel('time [ns]','FontName','Times New Roman','fontsize',10);
ylabel('Input Pulse','FontName','Times New Roman','fontsize',10);
set(gca,'FontName','Times New Roman','FontSize',10);
%%Calculate output pulse
output = conv(y1,tf);
x2 = linspace(0,length(output)*dt_in,length(output)-1)';
y2 = output;
figure;
plot(x2(1:9000),real(y2(1:9000)), '-b','LineWidth', 1);
grid on;
xlabel('time [ns]','FontName','Times New Roman','fontsize',10);
ylabel('Output Pulse','FontName','Times New Roman','fontsize',10);
set(gca,'FontName','Times New Roman','FontSize',10);
My guess is that something goes wrong in the ifft() procedure, since the input pulse is a gaussian pulse and as such the time domain transfer function should resemble the simulated output pulse. My second guess is that something in the synchronisation of the transfer function and input pulse is wrong (when trying to make their time steps equal).
Thoughts anyone?
0 Comments
Answers (1)
Hayden Arms
on 1 Nov 2022
Hello,
I know I'm a few years late but this code was very helpful for me, I think I solved it, it was in the resampling of the tf that I think you got mixed up. Heres my fix:
file = "passive.s2p";
sParam = sparameters(file); %get parameters
sFreq = sParam.Frequencies;
%% Approch with fourier
dt_in = 1/Fsamp; % sample time
tmax_in = dt_in*length(filtData); %full time of signal
dat_t = linspace(dt_in,tmax_in,length(filtData)); %timing of each input sample
% Convert sParameters to voltage transfer function
tf_f = s2tf(sParam);
% Calculate transfer function properties properties
df_tf = sParam.Frequencies(48) - sParam.Frequencies(47); % frequency resolution
N_tf = length(tf_f); % number of samples
Fs_tf = 2 * N_tf * df_tf; %2*df_tf; % sample frequency for upsampling (cranked)
dt_tf = 1/Fs_tf; % time step
tmax_tf = (1/df_tf)*N_tf;
% Convert frequency domain transfer function to time domain
tf = ifft(squeeze(sParam.Parameters(2,1,:)));
% Compensate time step difference between signal (td_in) and transfer function (td_tf)
tf = interp1(1:N_tf,tf,1:(tmax_tf/dt_tf)/(tmax_in/dt_in):N_tf, 'spline')'; %%%%%%%%%%%%
%%Input pulse interpolation
y1 = filtData;
x1 = dat_t;
%%Calculate output pulse
output = conv(filtData,tf);
x2 = linspace(0,length(output)*dt_in,length(output))';
x2 = x2(1:length(y1));
filteredSig = output(1:length(y1));
figure;
grid on;
plot(x2,real(filteredSig), '-b','LineWidth', 1,'Color','b');
hold on
plot(x1,y1, '-b','LineWidth', 1,'Color','r');
hold on
xlabel('time [ns]');
legend('Output','Input');
hold off
Not very cleaned up yet but it does work. Hope it helps anybody who finds this post.
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!