WIP: use Eigen::MatrixXcd in parameters in preparation for arbitrary number of ports

This commit is contained in:
Jan Käberich 2025-02-14 17:52:44 +01:00
parent ef8cdeccd7
commit d4df1c1b22
347 changed files with 270 additions and 197 deletions

View file

@ -7,7 +7,7 @@
#include "LibreCAL/librecaldialog.h" #include "LibreCAL/librecaldialog.h"
#include "preferences.h" #include "preferences.h"
#include "Eigen/Dense" #include "Tools/Eigen/Dense"
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
@ -777,25 +777,24 @@ Calibration::Point Calibration::computeSOLT(double f)
complex<double> S11, S21; complex<double> S11, S21;
Sparam Sideal; Sparam Sideal;
if(throughForward) { if(throughForward) {
S11 = throughForward->getMeasured(f).m11; S11 = throughForward->getMeasured(f).get(1,1);
S21 = throughForward->getMeasured(f).m21; S21 = throughForward->getMeasured(f).get(2,1);
Sideal = throughForward->getActual(f); Sideal = throughForward->getActual(f);
} else if(throughReverse) { } else if(throughReverse) {
S11 = throughReverse->getMeasured(f).m22; S11 = throughReverse->getMeasured(f).get(2,2);
S21 = throughReverse->getMeasured(f).m12; S21 = throughReverse->getMeasured(f).get(1,2);
Sideal = throughReverse->getActual(f); Sideal = throughReverse->getActual(f);
swap(Sideal.m11, Sideal.m22); Sideal.swapPorts(1,2);
swap(Sideal.m12, Sideal.m21);
} }
auto isoMeas = static_cast<CalibrationMeasurement::Isolation*>(findMeasurement(CalibrationMeasurement::Base::Type::Isolation)); auto isoMeas = static_cast<CalibrationMeasurement::Isolation*>(findMeasurement(CalibrationMeasurement::Base::Type::Isolation));
auto isolation = complex<double>(0.0,0.0); auto isolation = complex<double>(0.0,0.0);
if(isoMeas) { if(isoMeas) {
isolation = isoMeas->getMeasured(f, p2, p1); isolation = isoMeas->getMeasured(f, p2, p1);
} }
auto deltaS = Sideal.m11*Sideal.m22 - Sideal.m21 * Sideal.m12; auto deltaS = Sideal.get(1,1)*Sideal.get(2,2) - Sideal.get(2,1) * Sideal.get(1,2);
point.L[i][j] = ((S11 - point.D[i])*(1.0 - point.S[i] * Sideal.m11)-Sideal.m11*point.R[i]) point.L[i][j] = ((S11 - point.D[i])*(1.0 - point.S[i] * Sideal.get(1,1))-Sideal.get(1,1)*point.R[i])
/ ((S11 - point.D[i])*(Sideal.m22-point.S[i]*deltaS)-deltaS*point.R[i]); / ((S11 - point.D[i])*(Sideal.get(2,2)-point.S[i]*deltaS)-deltaS*point.R[i]);
point.T[i][j] = (S21 - isolation)*(1.0 - point.S[i]*Sideal.m11 - point.L[i][j]*Sideal.m22 + point.S[i]*point.L[i][j]*deltaS) / Sideal.m21; point.T[i][j] = (S21 - isolation)*(1.0 - point.S[i]*Sideal.get(1,1) - point.L[i][j]*Sideal.get(2,2) + point.S[i]*point.L[i][j]*deltaS) / Sideal.get(2,1);
point.I[i][j] = isolation; point.I[i][j] = isolation;
} }
} }
@ -828,15 +827,15 @@ Calibration::Point Calibration::computeThroughNormalization(double f)
complex<double> S21 = 0.0; complex<double> S21 = 0.0;
Sparam Sideal; Sparam Sideal;
if(throughForward) { if(throughForward) {
S21 = throughForward->getMeasured(f).m21; S21 = throughForward->getMeasured(f).get(2,1);
Sideal = throughForward->getActual(f); Sideal = throughForward->getActual(f);
} else if(throughReverse) { } else if(throughReverse) {
S21 = throughReverse->getMeasured(f).m12; S21 = throughReverse->getMeasured(f).get(1,2);
Sideal = throughReverse->getActual(f); Sideal = throughReverse->getActual(f);
swap(Sideal.m12, Sideal.m21); Sideal.swapPorts(1,2);
} }
point.L[i][j] = 0.0; point.L[i][j] = 0.0;
point.T[i][j] = S21 / Sideal.m21; point.T[i][j] = S21 / Sideal.get(2,1);
point.I[i][j] = 0.0; point.I[i][j] = 0.0;
} }
} }
@ -904,8 +903,7 @@ Calibration::Point Calibration::computeTRL(double freq)
Sthrough = throughForward->getMeasured(freq); Sthrough = throughForward->getMeasured(freq);
} else if(throughReverse) { } else if(throughReverse) {
Sthrough = throughReverse->getMeasured(freq); Sthrough = throughReverse->getMeasured(freq);
swap(Sthrough.m11, Sthrough.m22); Sthrough.swapPorts(1,2);
swap(Sthrough.m12, Sthrough.m21);
} }
// grab line measurement // grab line measurement
auto forwardLines = findMeasurements(CalibrationMeasurement::Base::Type::Line, p1, p2); auto forwardLines = findMeasurements(CalibrationMeasurement::Base::Type::Line, p1, p2);
@ -942,8 +940,7 @@ Calibration::Point Calibration::computeTRL(double freq)
Sparam Sline = closestLine->getMeasured(freq); Sparam Sline = closestLine->getMeasured(freq);
if(closestLineIsReversed) { if(closestLineIsReversed) {
swap(Sline.m11, Sline.m22); Sline.swapPorts(1,2);
swap(Sline.m12, Sline.m21);
} }
// got all required measurements // got all required measurements
@ -955,17 +952,17 @@ Calibration::Point Calibration::computeTRL(double freq)
auto T = R_D*R_T.inverse(); auto T = R_D*R_T.inverse();
complex<double> a_over_c, b; complex<double> a_over_c, b;
// page 21-22 // page 21-22
Util::solveQuadratic(T.m21, T.m22 - T.m11, -T.m12, b, a_over_c); Util::solveQuadratic(T.get(2,1), T.get(2,2) - T.get(1,1), -T.get(1,2), b, a_over_c);
// ensure correct root selection // ensure correct root selection
// page 23 // page 23
if(abs(b) >= abs(a_over_c)) { if(abs(b) >= abs(a_over_c)) {
swap(b, a_over_c); swap(b, a_over_c);
} }
// page 24 // page 24
auto g = R_T.m22; auto g = R_T.get(2,2);
auto d = R_T.m11 / g; auto d = R_T.get(1,1) / g;
auto e = R_T.m12 / g; auto e = R_T.get(1,2) / g;
auto f = R_T.m21 / g; auto f = R_T.get(2,1) / g;
// page 25 // page 25
auto r22_rho22 = g * (1.0 - e / a_over_c) / (1.0 - b / a_over_c); auto r22_rho22 = g * (1.0 - e / a_over_c) / (1.0 - b / a_over_c);
@ -994,12 +991,12 @@ Calibration::Point Calibration::computeTRL(double freq)
auto Box_A = Tparam(r22 * a, r22 * b, r22 * c, r22); auto Box_A = Tparam(r22 * a, r22 * b, r22 * c, r22);
auto Box_B = Tparam(rho22 * alpha, rho22 * beta, rho22 * gamma, rho22); auto Box_B = Tparam(rho22 * alpha, rho22 * beta, rho22 * gamma, rho22);
auto S_A = Sparam(Box_A); auto S_A = Sparam(Box_A);
point.D[i] = S_A.m11; point.D[i] = S_A.get(1,1);
point.R[i] = S_A.m12; point.R[i] = S_A.get(1,2);
point.S[i] = S_A.m22; point.S[i] = S_A.get(2,2);
auto S_B = Sparam(Box_B); auto S_B = Sparam(Box_B);
point.L[i][j] = S_B.m11; point.L[i][j] = S_B.get(1,1);
point.T[i][j] = S_B.m21; point.T[i][j] = S_B.get(2,1);
// no isolation measurement available // no isolation measurement available
point.I[i][j] = 0.0; point.I[i][j] = 0.0;
@ -1153,13 +1150,13 @@ std::vector<Trace *> Calibration::getMeasurementTraces()
for(auto d : twoPort->getPoints()) { for(auto d : twoPort->getPoints()) {
Trace::Data td; Trace::Data td;
td.x = d.frequency; td.x = d.frequency;
td.y = d.S.m11; td.y = d.S.get(1,1);
ts11->addData(td, Trace::DataType::Frequency); ts11->addData(td, Trace::DataType::Frequency);
td.y = d.S.m12; td.y = d.S.get(1,2);
ts12->addData(td, Trace::DataType::Frequency); ts12->addData(td, Trace::DataType::Frequency);
td.y = d.S.m21; td.y = d.S.get(2,1);
ts21->addData(td, Trace::DataType::Frequency); ts21->addData(td, Trace::DataType::Frequency);
td.y = d.S.m22; td.y = d.S.get(2,2);
ts22->addData(td, Trace::DataType::Frequency); ts22->addData(td, Trace::DataType::Frequency);
} }
ret.push_back(ts11); ret.push_back(ts11);

View file

@ -564,8 +564,7 @@ Sparam CalibrationMeasurement::TwoPort::getActual(double frequency)
{ {
auto param = static_cast<CalStandard::TwoPort*>(standard)->toSparam(frequency); auto param = static_cast<CalStandard::TwoPort*>(standard)->toSparam(frequency);
if(reverseStandard) { if(reverseStandard) {
swap(param.m11, param.m22); param.swapPorts(1, 2);
swap(param.m12, param.m21);
} }
return param; return param;
} }

View file

@ -734,10 +734,10 @@ Sparam Line::toSparam(double freq)
{ {
Q_UNUSED(freq) Q_UNUSED(freq)
Sparam ret; Sparam ret;
ret.m11 = numeric_limits<complex<double>>::quiet_NaN(); ret.set(1,1,numeric_limits<complex<double>>::quiet_NaN());
ret.m12 = numeric_limits<complex<double>>::quiet_NaN(); ret.set(1,2,numeric_limits<complex<double>>::quiet_NaN());
ret.m21 = numeric_limits<complex<double>>::quiet_NaN(); ret.set(2,1,numeric_limits<complex<double>>::quiet_NaN());
ret.m22 = numeric_limits<complex<double>>::quiet_NaN(); ret.set(2,2,numeric_limits<complex<double>>::quiet_NaN());
return ret; return ret;
} }

View file

@ -64,10 +64,10 @@ unsigned int DeviceDriver::SApoints() {
Sparam DeviceDriver::VNAMeasurement::toSparam(int port1, int port2) const Sparam DeviceDriver::VNAMeasurement::toSparam(int port1, int port2) const
{ {
Sparam S; Sparam S;
S.m11 = measurements.at("S"+QString::number(port1)+QString::number(port1)); S.set(1,1, measurements.at("S"+QString::number(port1)+QString::number(port1)));
S.m12 = measurements.at("S"+QString::number(port1)+QString::number(port2)); S.set(1,2, measurements.at("S"+QString::number(port1)+QString::number(port2)));
S.m21 = measurements.at("S"+QString::number(port2)+QString::number(port1)); S.set(2,1, measurements.at("S"+QString::number(port2)+QString::number(port1)));
S.m22 = measurements.at("S"+QString::number(port2)+QString::number(port2)); S.set(2,2, measurements.at("S"+QString::number(port2)+QString::number(port2)));
return S; return S;
} }
@ -78,16 +78,16 @@ void DeviceDriver::VNAMeasurement::fromSparam(Sparam S, int port1, int port2)
QString s21 = "S"+QString::number(port2)+QString::number(port1); QString s21 = "S"+QString::number(port2)+QString::number(port1);
QString s22 = "S"+QString::number(port2)+QString::number(port2); QString s22 = "S"+QString::number(port2)+QString::number(port2);
if(measurements.count(s11)) { if(measurements.count(s11)) {
measurements[s11] = S.m11; measurements[s11] = S.get(1,1);
} }
if(measurements.count(s12)) { if(measurements.count(s12)) {
measurements[s12] = S.m12; measurements[s12] = S.get(1,2);
} }
if(measurements.count(s21)) { if(measurements.count(s21)) {
measurements[s21] = S.m21; measurements[s21] = S.get(2,1);
} }
if(measurements.count(s22)) { if(measurements.count(s22)) {
measurements[s22] = S.m22; measurements[s22] = S.get(2,2);
} }
} }

Some files were not shown because too many files have changed in this diff Show more