mirror of
https://github.com/jankae/LibreVNA.git
synced 2025-12-06 07:12:10 +01:00
WIP: use Eigen::MatrixXcd in parameters in preparation for arbitrary number of ports
This commit is contained in:
parent
ef8cdeccd7
commit
d4df1c1b22
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
Loading…
Reference in a new issue