mirror of
https://github.com/njchorda/MATLAB-Touchstone-Reader.git
synced 2026-02-25 11:00:45 -05:00
Add files via upload
This commit is contained in:
137
SPARAMS.m
137
SPARAMS.m
@@ -1,6 +1,4 @@
|
|||||||
classdef SPARAMS < handle
|
classdef SPARAMS < handle
|
||||||
% Author: Nathan Chordas-Ewell
|
|
||||||
% Written: 2020
|
|
||||||
%Works on up to 4 port measurements in RI, MA, dBA formats (Som
|
%Works on up to 4 port measurements in RI, MA, dBA formats (Som
|
||||||
%Usage:
|
%Usage:
|
||||||
% s = SPARAMS('filename')
|
% s = SPARAMS('filename')
|
||||||
@@ -32,6 +30,10 @@ classdef SPARAMS < handle
|
|||||||
%Deembed S parameters to the DUT. Returns an SPARAMS object of the DUT
|
%Deembed S parameters to the DUT. Returns an SPARAMS object of the DUT
|
||||||
% P1 <--err1--DUT--err2--> P2
|
% P1 <--err1--DUT--err2--> P2
|
||||||
% DUT = SPARAMS.deembed(err1, measured, err2)
|
% DUT = SPARAMS.deembed(err1, measured, err2)
|
||||||
|
%Write data to new touchstone file
|
||||||
|
% s.writeSNP(filename)
|
||||||
|
% File format is already taken care of, but s.serNumPorts() must be
|
||||||
|
% called first to know which file type to write (s1p, s2p, s3p, s4p)
|
||||||
|
|
||||||
properties
|
properties
|
||||||
f;
|
f;
|
||||||
@@ -59,6 +61,9 @@ classdef SPARAMS < handle
|
|||||||
function setFile(obj, fname)
|
function setFile(obj, fname)
|
||||||
%If you wish to set a filename after creating the object. Also
|
%If you wish to set a filename after creating the object. Also
|
||||||
%called when initializing with a sNp file.
|
%called when initializing with a sNp file.
|
||||||
|
if isstring(fname)
|
||||||
|
fname = convertStringsToChars(fname);
|
||||||
|
end
|
||||||
obj.filename = fname;
|
obj.filename = fname;
|
||||||
obj.txt2data();
|
obj.txt2data();
|
||||||
obj.getFormat();
|
obj.getFormat();
|
||||||
@@ -117,7 +122,9 @@ classdef SPARAMS < handle
|
|||||||
obj.numPorts = str2num(fExt(3));
|
obj.numPorts = str2num(fExt(3));
|
||||||
txt = fileread(obj.filename);
|
txt = fileread(obj.filename);
|
||||||
key = '#';
|
key = '#';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
txt = strtrim(txt);
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
txt = regexprep(txt, '![\s\S]*?!|([^:]|^)!.*$', '', 'lineanchors', 'dotexceptnewline');
|
txt = regexprep(txt, '![\s\S]*?!|([^:]|^)!.*$', '', 'lineanchors', 'dotexceptnewline');
|
||||||
txt = regexprep(txt, '\t+', ' '); %Remove all tabs and replace with s single space (dealt with in next line)
|
txt = regexprep(txt, '\t+', ' '); %Remove all tabs and replace with s single space (dealt with in next line)
|
||||||
txt = strtrim(txt); %Remove trailing whitespace
|
txt = strtrim(txt); %Remove trailing whitespace
|
||||||
@@ -259,7 +266,7 @@ classdef SPARAMS < handle
|
|||||||
[~, ind] = min(abs(obj.f-freq));
|
[~, ind] = min(abs(obj.f-freq));
|
||||||
fAct = obj.f(ind);
|
fAct = obj.f(ind);
|
||||||
if obj.f(ind) ~= freq
|
if obj.f(ind) ~= freq
|
||||||
warning('Not a frequency in list, using %d', obj.f(ind));
|
warning('Not a frequency in list, using %d GHz instead of the specified %d GHz', obj.f(ind)/1e9, freq/1e9);
|
||||||
end
|
end
|
||||||
switch obj.numPorts
|
switch obj.numPorts
|
||||||
case 1
|
case 1
|
||||||
@@ -333,7 +340,7 @@ classdef SPARAMS < handle
|
|||||||
end
|
end
|
||||||
|
|
||||||
function plotdB(obj, splt)
|
function plotdB(obj, splt)
|
||||||
%Plots any speciified S-parameter(s) in dB format
|
%Plots any speciified S-parameter(s) in dB formatboi
|
||||||
%Say you wish to plot only S11 and S21
|
%Say you wish to plot only S11 and S21
|
||||||
%s.plotdB({'S11' 'S21'})
|
%s.plotdB({'S11' 'S21'})
|
||||||
hold on
|
hold on
|
||||||
@@ -451,7 +458,7 @@ classdef SPARAMS < handle
|
|||||||
Zin2 = obj.Z0.*(1 + obj.S22)./(1 - obj.S22);
|
Zin2 = obj.Z0.*(1 + obj.S22)./(1 - obj.S22);
|
||||||
end
|
end
|
||||||
|
|
||||||
function [A, B, C, D] = toABCD(obj, freq)
|
function [A, B, C, D] = toABCDparams(obj, freq)
|
||||||
%Calculates the ABCD parameters from S-parameters
|
%Calculates the ABCD parameters from S-parameters
|
||||||
%[A, B, C, D] = s.toABCD(); for all frequencies (s.f)
|
%[A, B, C, D] = s.toABCD(); for all frequencies (s.f)
|
||||||
%[A, B, C, D] = s.toABCD(freq); for a specified frequency
|
%[A, B, C, D] = s.toABCD(freq); for a specified frequency
|
||||||
@@ -513,25 +520,25 @@ classdef SPARAMS < handle
|
|||||||
case 1
|
case 1
|
||||||
obj.S11 = S11n;
|
obj.S11 = S11n;
|
||||||
case 2
|
case 2
|
||||||
obj.S11 = S11n; obj.S12 = S12n; obj.S21 = S21n; obj.S22 = S22n;
|
obj.S11 = S11n'; obj.S12 = S12n'; obj.S21 = S21n'; obj.S22 = S22n';
|
||||||
end
|
end
|
||||||
obj.setZ0(Z0new);
|
obj.setZ0(Z0new);
|
||||||
end
|
end
|
||||||
|
|
||||||
function [Z11, Z12, Z21, Z22] = toZparams(obj, freq)
|
function [Z11, Z12, Z21, Z22] = toZparams(obj)
|
||||||
%Calculate Z parameters from S-parameters
|
%Calculate Z parameters from S-parameters
|
||||||
%[Z11, Z12, Z21, Z22] = toZparams(); for all frequencies (s.f)
|
%[Z11, Z12, Z21, Z22] = toZparams(); for all frequencies (s.f)
|
||||||
%[Z11, Z12, Z21, Z22] = toZparams(freq); for a specified frequency
|
%[Z11, Z12, Z21, Z22] = toZparams(freq); for a specified frequency
|
||||||
if obj.numPorts ~= 2
|
if obj.numPorts ~= 2
|
||||||
warning('Only for 2 port measurements');
|
warning('Only for 2 port measurements');
|
||||||
end
|
end
|
||||||
switch nargin
|
% switch nargin
|
||||||
case 2
|
% case 2
|
||||||
fS11 = obj.S11; fS12 = obj.S12; fS21 = obj.S21; fS22 = obj.S22;
|
fS11 = obj.S11; fS12 = obj.S12; fS21 = obj.S21; fS22 = obj.S22;
|
||||||
case 3
|
% case 3
|
||||||
S = obj.toMat(freq);
|
% S = obj.toMat(freq);
|
||||||
fS11 = S(1, 1); fS12 = S(1, 2); fS21 = S(2, 1); fS22 = S(2, 2);
|
% fS11 = S(1, 1); fS12 = S(1, 2); fS21 = S(2, 1); fS22 = S(2, 2);
|
||||||
end
|
% end
|
||||||
Z11 = obj.Z0*((1 + fS11).*(1 - fS22) + fS12.*fS21)./((1 - fS11).*(1 - fS22) - fS12.*fS21);
|
Z11 = obj.Z0*((1 + fS11).*(1 - fS22) + fS12.*fS21)./((1 - fS11).*(1 - fS22) - fS12.*fS21);
|
||||||
Z12 = obj.Z0*(2.*fS12)./((1 - fS11).*(1 - fS22) - fS12.*fS21);
|
Z12 = obj.Z0*(2.*fS12)./((1 - fS11).*(1 - fS22) - fS12.*fS21);
|
||||||
Z21 = obj.Z0*(2*fS21)./((1 - fS11).*(1 - fS22) - fS12.*fS21);
|
Z21 = obj.Z0*(2*fS21)./((1 - fS11).*(1 - fS22) - fS12.*fS21);
|
||||||
@@ -545,13 +552,14 @@ classdef SPARAMS < handle
|
|||||||
if obj.numPorts ~= 2
|
if obj.numPorts ~= 2
|
||||||
warning('Only for 2 port measurements');
|
warning('Only for 2 port measurements');
|
||||||
end
|
end
|
||||||
switch nargin
|
fS11 = obj.S11; fS12 = obj.S12; fS21 = obj.S21; fS22 = obj.S22;
|
||||||
case 2
|
% switch nargin
|
||||||
fS11 = obj.S11; fS12 = obj.S12; fS21 = obj.S21; fS22 = obj.S22;
|
% case 2
|
||||||
case 3
|
% fS11 = obj.S11; fS12 = obj.S12; fS21 = obj.S21; fS22 = obj.S22;
|
||||||
S = obj.toMat(freq);
|
% case 3
|
||||||
fS11 = S(1, 1); fS12 = S(1, 2); fS21 = S(2, 1); fS22 = S(2, 2);
|
% S = obj.toMat(freq);
|
||||||
end
|
% fS11 = S(1, 1); fS12 = S(1, 2); fS21 = S(2, 1); fS22 = S(2, 2);
|
||||||
|
% end
|
||||||
delS = (1 + fS11).*(1 + fS22) - fS12.*fS21;
|
delS = (1 + fS11).*(1 + fS22) - fS12.*fS21;
|
||||||
Y11 = ((1 - fS11).*(1 + fS22) + fS12.*fS21)./delS./obj.Z0;
|
Y11 = ((1 - fS11).*(1 + fS22) + fS12.*fS21)./delS./obj.Z0;
|
||||||
Y12 = -2.*fS12./delS./obj.Z0;
|
Y12 = -2.*fS12./delS./obj.Z0;
|
||||||
@@ -574,12 +582,49 @@ classdef SPARAMS < handle
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
%Work in progress
|
% Work in progress
|
||||||
% function writeSNP(obj, filenameOut)
|
function writeSNP(obj, filenameOut)
|
||||||
% fileExt = ['.s' num2str(obj.numPorts), 'p'];
|
fileExt = ['.s' num2str(obj.numPorts), 'p'];
|
||||||
%
|
headerStr = ['# GHZ S RI R ', num2str(obj.Z0)];
|
||||||
% dlmwrite(filenameOut, obj.data, ' ');
|
% headerStr = "asfsafsadf"
|
||||||
% end
|
switch obj.numPorts
|
||||||
|
case 1
|
||||||
|
S11re = real(obj.S11);S11im = imag(obj.S11);
|
||||||
|
dataWrite = table(obj.f'/1e9, S11re', S11im');
|
||||||
|
dataWrite.Properties.VariableNames = [headerStr, " ", " "];
|
||||||
|
writetable(dataWrite, [filenameOut fileExt], 'FileType','text', 'Delimiter', '\t', 'WriteVariableNames',true)
|
||||||
|
case 2
|
||||||
|
dataWrite = table(obj.f'/1e9, real(obj.S11)', imag(obj.S11)', real(obj.S21)',imag(obj.S21)',real(obj.S12)',imag(obj.S12)',real(obj.S22)',imag(obj.S22)');
|
||||||
|
names = headerStr;
|
||||||
|
for i = 1:8
|
||||||
|
names = [names convertCharsToStrings(blanks(i))];
|
||||||
|
end
|
||||||
|
dataWrite.Properties.VariableNames = names;%[headerStr, " ", " ", " ", " ", " ", " ", " ", " "];
|
||||||
|
writetable(dataWrite, [filenameOut fileExt], 'FileType','text', 'Delimiter', '\t', 'WriteVariableNames',true)
|
||||||
|
case 3
|
||||||
|
dataWrite = table(obj.f'/1e9, real(obj.S11)', imag(obj.S11)', real(obj.S12)',imag(obj.S12)', real(obj.S13)', imag(obj.S13)',...
|
||||||
|
real(obj.S21)', imag(obj.S21)', real(obj.S22)',imag(obj.S22)', real(obj.S23)', imag(obj.S23)',...
|
||||||
|
real(obj.S31)', imag(obj.S31)', real(obj.S32)',imag(obj.S32)', real(obj.S33)', imag(obj.S33)');
|
||||||
|
names = headerStr;
|
||||||
|
for i = 1:18
|
||||||
|
names = [names convertCharsToStrings(blanks(i))];
|
||||||
|
end
|
||||||
|
dataWrite.Properties.VariableNames = names;
|
||||||
|
writetable(dataWrite, [filenameOut fileExt], 'FileType','text', 'Delimiter', '\t', 'WriteVariableNames',true)
|
||||||
|
case 4
|
||||||
|
dataWrite = table(obj.f'/1e9, real(obj.S11)', imag(obj.S11)', real(obj.S12)',imag(obj.S12)', real(obj.S13)', imag(obj.S13)', real(obj.S14)', imag(obj.S14)',...
|
||||||
|
real(obj.S21)', imag(obj.S21)', real(obj.S22)',imag(obj.S22)', real(obj.S23)', imag(obj.S23)', real(obj.S24)', imag(obj.S24)',...
|
||||||
|
real(obj.S31)', imag(obj.S31)', real(obj.S32)',imag(obj.S32)', real(obj.S33)', imag(obj.S33)', real(obj.S34)', imag(obj.S34)',...
|
||||||
|
real(obj.S31)', imag(obj.S31)', real(obj.S32)',imag(obj.S32)', real(obj.S33)', imag(obj.S33)', real(obj.S34)', imag(obj.S34)');
|
||||||
|
names = headerStr;
|
||||||
|
for i = 1:32
|
||||||
|
names = [names convertCharsToStrings(blanks(i))];
|
||||||
|
end
|
||||||
|
dataWrite.Properties.VariableNames = names;
|
||||||
|
writetable(dataWrite, [filenameOut fileExt], 'FileType','text', 'Delimiter', '\t', 'WriteVariableNames',true)
|
||||||
|
end
|
||||||
|
% dlmwrite(filenameOut, obj.data, ' ');
|
||||||
|
end
|
||||||
|
|
||||||
function cascade(obj, N)
|
function cascade(obj, N)
|
||||||
%Calculates S parameters when cascaded N times. Only valid for
|
%Calculates S parameters when cascaded N times. Only valid for
|
||||||
@@ -587,7 +632,7 @@ classdef SPARAMS < handle
|
|||||||
%This function will overwrite the original S-parameters, so it
|
%This function will overwrite the original S-parameters, so it
|
||||||
%may be advisable to copy the original unit cell first using
|
%may be advisable to copy the original unit cell first using
|
||||||
%copyobj()
|
%copyobj()
|
||||||
[Au, Bu, Cu, Du] = obj.toABCD;
|
[Au, Bu, Cu, Du] = obj.toABCDparams;
|
||||||
At = Au; Bt = Bu; Ct = Cu; Dt = Du;
|
At = Au; Bt = Bu; Ct = Cu; Dt = Du;
|
||||||
for i = 1:N-1
|
for i = 1:N-1
|
||||||
Attemp = At; Bttemp = Bt; Cttemp = Ct; Dttemp = Dt;
|
Attemp = At; Bttemp = Bt; Cttemp = Ct; Dttemp = Dt;
|
||||||
@@ -609,16 +654,16 @@ classdef SPARAMS < handle
|
|||||||
%Beta_p = acos((1 - S(1,1)*S(2,2) + S(1,2)*S(2,1))/(2*S(2,1)))
|
%Beta_p = acos((1 - S(1,1)*S(2,2) + S(1,2)*S(2,1))/(2*S(2,1)))
|
||||||
switch nargin
|
switch nargin
|
||||||
case 1
|
case 1
|
||||||
plot(Beta_p, obj.f/obj.freqScale{1}, 'k');
|
plot(obj.f/obj.freqScale{1}, Beta_p, 'k');
|
||||||
ylabel(['f (' obj.freqScale{2} ')'])
|
ylabel('\beta p (deg)')
|
||||||
xlabel('\beta p (deg)')
|
xlabel(['f (' obj.freqScale{2} ')'])
|
||||||
case 2
|
case 2
|
||||||
if ~strcmpi(flip, 'flip')
|
if ~strcmpi(flip, 'flip')
|
||||||
plot(Beta_p, obj.f/obj.freqScale{1}, 'k');
|
plot(obj.f/obj.freqScale{1}, Beta_p, 'k');
|
||||||
ylabel(['f (' obj.freqScale{2} ')'])
|
ylabel(['f (' obj.freqScale{2} ')'])
|
||||||
xlabel('\beta p (deg)')
|
xlabel('\beta p (deg)')
|
||||||
else
|
else
|
||||||
plot(obj.f/obj.freqScale{1}, Beta_p, 'k');
|
plot(Beta_p, obj.f/obj.freqScale{1}, 'k');
|
||||||
xlabel(['f (' obj.freqScale{2} ')'])
|
xlabel(['f (' obj.freqScale{2} ')'])
|
||||||
ylabel('\beta p (deg)')
|
ylabel('\beta p (deg)')
|
||||||
end
|
end
|
||||||
@@ -682,14 +727,14 @@ classdef SPARAMS < handle
|
|||||||
for i = 1:length(splt1)
|
for i = 1:length(splt1)
|
||||||
stringToPlot = ['ob1.' splt1{i}];
|
stringToPlot = ['ob1.' splt1{i}];
|
||||||
stoPlot = eval(stringToPlot);
|
stoPlot = eval(stringToPlot);
|
||||||
plot(ob1.f, 20*log10(abs(stoPlot)));
|
plot(ob1.f/1e9, 20*log10(abs(stoPlot)));
|
||||||
end
|
end
|
||||||
for i = 1:length(splt2)
|
for i = 1:length(splt2)
|
||||||
stringToPlot = ['ob2.' splt2{i}];
|
stringToPlot = ['ob2.' splt2{i}];
|
||||||
stoPlot = eval(stringToPlot);
|
stoPlot = eval(stringToPlot);
|
||||||
plot(ob2.f, 20*log10(abs(stoPlot)));
|
plot(ob2.f/1e9, 20*log10(abs(stoPlot)));
|
||||||
end
|
end
|
||||||
xlabel('f (Hz)');
|
xlabel('f (GHz)');
|
||||||
ylabel('S-parameters (dB)');
|
ylabel('S-parameters (dB)');
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -712,6 +757,22 @@ classdef SPARAMS < handle
|
|||||||
S21 = 2*Z21.*Z0./dZ;
|
S21 = 2*Z21.*Z0./dZ;
|
||||||
S22 = ((Z11 + Z0).*(Z22 - Z0) - Z12.*Z21)/dZ;s
|
S22 = ((Z11 + Z0).*(Z22 - Z0) - Z12.*Z21)/dZ;s
|
||||||
S = [S11 S12;S21 S22];
|
S = [S11 S12;S21 S22];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function [A, B, C, D] = s2abcd(S, Z0)
|
||||||
|
A = ((1 + S(1,1)).*(1 - S(2,2)) + S(1,2).*S(2,1))./(2.*S(2,1));
|
||||||
|
B = Z0*((1 + S(1,1)).*(1 + S(2,2)) - S(1,2).*S(2,1))./(2.*S(2,1));
|
||||||
|
C = (1/Z0)*((1 - S(1,1)).*(1 - S(2,2)) - S(1,2).*S(2,1))./(2*S(2,1));
|
||||||
|
D = ((1 - S(1,1)).*(1 + S(2,2)) + S(1,2).*S(2,1))./(2*S(2,1));
|
||||||
|
end
|
||||||
|
|
||||||
|
function [S11, S21, S12, S22] = abcd2s(A, B, C, D, Z0)
|
||||||
|
denom = A + B./Z0 + C.*Z0 + D;
|
||||||
|
S11 = (A + B./Z0 - C.*Z0 - D)./denom;
|
||||||
|
S12 = 2.*(A.*D - B.*C)./denom;
|
||||||
|
S21 = 2./denom;
|
||||||
|
S22 = (-A + B./Z0 - C.*Z0 + D)./denom;
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user