Through normalization and TRL calibration added
This commit is contained in:
parent
c6d9796a11
commit
49917c4b19
@ -42,31 +42,7 @@ void Calibration::addMeasurement(Calibration::Measurement type, Protocol::Datapo
|
||||
|
||||
bool Calibration::calculationPossible(Calibration::Type type)
|
||||
{
|
||||
std::vector<Measurement> requiredMeasurements;
|
||||
switch(type) {
|
||||
case Type::Port1SOL:
|
||||
requiredMeasurements.push_back(Measurement::Port1Open);
|
||||
requiredMeasurements.push_back(Measurement::Port1Short);
|
||||
requiredMeasurements.push_back(Measurement::Port1Load);
|
||||
break;
|
||||
case Type::Port2SOL:
|
||||
requiredMeasurements.push_back(Measurement::Port2Open);
|
||||
requiredMeasurements.push_back(Measurement::Port2Short);
|
||||
requiredMeasurements.push_back(Measurement::Port2Load);
|
||||
break;
|
||||
case Type::FullSOLT:
|
||||
requiredMeasurements.push_back(Measurement::Port1Open);
|
||||
requiredMeasurements.push_back(Measurement::Port1Short);
|
||||
requiredMeasurements.push_back(Measurement::Port1Load);
|
||||
requiredMeasurements.push_back(Measurement::Port2Open);
|
||||
requiredMeasurements.push_back(Measurement::Port2Short);
|
||||
requiredMeasurements.push_back(Measurement::Port2Load);
|
||||
requiredMeasurements.push_back(Measurement::Through);
|
||||
break;
|
||||
case Type::None:
|
||||
return false;
|
||||
}
|
||||
return SanityCheckSamples(requiredMeasurements);
|
||||
return SanityCheckSamples(Measurements(type, false));
|
||||
}
|
||||
|
||||
bool Calibration::constructErrorTerms(Calibration::Type type)
|
||||
@ -74,23 +50,19 @@ bool Calibration::constructErrorTerms(Calibration::Type type)
|
||||
if(!calculationPossible(type)) {
|
||||
return false;
|
||||
}
|
||||
if(minFreq < kit.minFreq() || maxFreq > kit.maxFreq()) {
|
||||
bool isTRL = type == Type::TRL;
|
||||
if(minFreq < kit.minFreq(isTRL) || maxFreq > kit.maxFreq(isTRL)) {
|
||||
// Calkit does not support complete calibration range
|
||||
QMessageBox::critical(nullptr, "Unable to perform calibration", "The calibration kit does not support the complete span. Please choose a different calibration kit or a narrower span.");
|
||||
return false;
|
||||
}
|
||||
switch(type) {
|
||||
case Type::Port1SOL:
|
||||
constructPort1SOL();
|
||||
break;
|
||||
case Type::Port2SOL:
|
||||
constructPort2SOL();
|
||||
break;
|
||||
case Type::FullSOLT:
|
||||
construct12TermPoints();
|
||||
break;
|
||||
case Type::None:
|
||||
break;
|
||||
case Type::Port1SOL: constructPort1SOL(); break;
|
||||
case Type::Port2SOL: constructPort2SOL(); break;
|
||||
case Type::FullSOLT: construct12TermPoints(); break;
|
||||
case Type::TransmissionNormalization: constructTransmissionNormalization(); break;
|
||||
case Type::TRL: constructTRL(); break;
|
||||
case Type::None: break;
|
||||
}
|
||||
this->type = type;
|
||||
return true;
|
||||
@ -104,17 +76,7 @@ void Calibration::resetErrorTerms()
|
||||
|
||||
void Calibration::construct12TermPoints()
|
||||
{
|
||||
std::vector<Measurement> requiredMeasurements;
|
||||
requiredMeasurements.push_back(Measurement::Port1Open);
|
||||
requiredMeasurements.push_back(Measurement::Port1Short);
|
||||
requiredMeasurements.push_back(Measurement::Port1Load);
|
||||
requiredMeasurements.push_back(Measurement::Port2Open);
|
||||
requiredMeasurements.push_back(Measurement::Port2Short);
|
||||
requiredMeasurements.push_back(Measurement::Port2Load);
|
||||
requiredMeasurements.push_back(Measurement::Through);
|
||||
if(!SanityCheckSamples(requiredMeasurements)) {
|
||||
throw runtime_error("Missing/wrong calibration measurement");
|
||||
}
|
||||
std::vector<Measurement> requiredMeasurements = Measurements(Type::FullSOLT);
|
||||
requiredMeasurements.push_back(Measurement::Isolation);
|
||||
bool isolation_measured = SanityCheckSamples(requiredMeasurements);
|
||||
|
||||
@ -141,11 +103,11 @@ void Calibration::construct12TermPoints()
|
||||
auto S22_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S22, measurements[Measurement::Through].datapoints[i].imag_S22);
|
||||
auto S12_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S12, measurements[Measurement::Through].datapoints[i].imag_S12);
|
||||
|
||||
auto actual = kit.toReflection(p.frequency);
|
||||
auto actual = kit.toSOLT(p.frequency);
|
||||
// Forward calibration
|
||||
computeSOL(S11_short, S11_open, S11_load, p.fe00, p.fe11, p.fe10e01, actual.Open, actual.Short, actual.Load);
|
||||
p.fe30 = S21_isolation;
|
||||
// See page 17 of http://www2.electron.frba.utn.edu.ar/~jcecconi/Bibliografia/04%20-%20Param_S_y_VNA/Network_Analyzer_Error_Models_and_Calibration_Methods.pdf
|
||||
// See page 18 of https://www.rfmentor.com/sites/default/files/NA_Error_Models_and_Cal_Methods.pdf
|
||||
// Formulas for S11M and S21M solved for e22 and e10e32
|
||||
auto deltaS = actual.ThroughS11*actual.ThroughS22 - actual.ThroughS21 * actual.ThroughS12;
|
||||
p.fe22 = ((S11_through - p.fe00)*(1.0 - p.fe11 * actual.ThroughS11)-actual.ThroughS11*p.fe10e01)
|
||||
@ -163,15 +125,6 @@ void Calibration::construct12TermPoints()
|
||||
|
||||
void Calibration::constructPort1SOL()
|
||||
{
|
||||
std::vector<Measurement> requiredMeasurements;
|
||||
requiredMeasurements.push_back(Measurement::Port1Open);
|
||||
requiredMeasurements.push_back(Measurement::Port1Short);
|
||||
requiredMeasurements.push_back(Measurement::Port1Load);
|
||||
if(!SanityCheckSamples(requiredMeasurements)) {
|
||||
throw runtime_error("Missing/wrong calibration measurement");
|
||||
}
|
||||
|
||||
// If we get here the calibration measurements are all okay
|
||||
points.clear();
|
||||
for(unsigned int i = 0;i<measurements[Measurement::Port1Open].datapoints.size();i++) {
|
||||
Point p;
|
||||
@ -181,8 +134,8 @@ void Calibration::constructPort1SOL()
|
||||
auto S11_short = complex<double>(measurements[Measurement::Port1Short].datapoints[i].real_S11, measurements[Measurement::Port1Short].datapoints[i].imag_S11);
|
||||
auto S11_load = complex<double>(measurements[Measurement::Port1Load].datapoints[i].real_S11, measurements[Measurement::Port1Load].datapoints[i].imag_S11);
|
||||
// OSL port1
|
||||
auto actual = kit.toReflection(p.frequency);
|
||||
// See page 19 of http://www2.electron.frba.utn.edu.ar/~jcecconi/Bibliografia/04%20-%20Param_S_y_VNA/Network_Analyzer_Error_Models_and_Calibration_Methods.pdf
|
||||
auto actual = kit.toSOLT(p.frequency);
|
||||
// See page 13 of https://www.rfmentor.com/sites/default/files/NA_Error_Models_and_Cal_Methods.pdf
|
||||
computeSOL(S11_short, S11_open, S11_load, p.fe00, p.fe11, p.fe10e01, actual.Open, actual.Short, actual.Load);
|
||||
// All other calibration coefficients to ideal values
|
||||
p.fe30 = 0.0;
|
||||
@ -200,15 +153,6 @@ void Calibration::constructPort1SOL()
|
||||
|
||||
void Calibration::constructPort2SOL()
|
||||
{
|
||||
std::vector<Measurement> requiredMeasurements;
|
||||
requiredMeasurements.push_back(Measurement::Port2Open);
|
||||
requiredMeasurements.push_back(Measurement::Port2Short);
|
||||
requiredMeasurements.push_back(Measurement::Port2Load);
|
||||
if(!SanityCheckSamples(requiredMeasurements)) {
|
||||
throw runtime_error("Missing/wrong calibration measurement");
|
||||
}
|
||||
|
||||
// If we get here the calibration measurements are all okay
|
||||
points.clear();
|
||||
for(unsigned int i = 0;i<measurements[Measurement::Port2Open].datapoints.size();i++) {
|
||||
Point p;
|
||||
@ -218,8 +162,8 @@ void Calibration::constructPort2SOL()
|
||||
auto S22_short = complex<double>(measurements[Measurement::Port2Short].datapoints[i].real_S22, measurements[Measurement::Port2Short].datapoints[i].imag_S22);
|
||||
auto S22_load = complex<double>(measurements[Measurement::Port2Load].datapoints[i].real_S22, measurements[Measurement::Port2Load].datapoints[i].imag_S22);
|
||||
// OSL port2
|
||||
auto actual = kit.toReflection(p.frequency);
|
||||
// See page 19 of http://www2.electron.frba.utn.edu.ar/~jcecconi/Bibliografia/04%20-%20Param_S_y_VNA/Network_Analyzer_Error_Models_and_Calibration_Methods.pdf
|
||||
auto actual = kit.toSOLT(p.frequency);
|
||||
// See page 19 of https://www.rfmentor.com/sites/default/files/NA_Error_Models_and_Cal_Methods.pdf
|
||||
computeSOL(S22_short, S22_open, S22_load, p.re33, p.re22, p.re23e32, actual.Open, actual.Short, actual.Load);
|
||||
// All other calibration coefficients to ideal values
|
||||
p.fe30 = 0.0;
|
||||
@ -235,6 +179,187 @@ void Calibration::constructPort2SOL()
|
||||
}
|
||||
}
|
||||
|
||||
void Calibration::constructTransmissionNormalization()
|
||||
{
|
||||
points.clear();
|
||||
for(unsigned int i = 0;i<measurements[Measurement::Through].datapoints.size();i++) {
|
||||
Point p;
|
||||
p.frequency = measurements[Measurement::Through].datapoints[i].frequency;
|
||||
// extract required complex reflection/transmission factors from datapoints
|
||||
auto S21_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S21, measurements[Measurement::Through].datapoints[i].imag_S21);
|
||||
auto S12_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S12, measurements[Measurement::Through].datapoints[i].imag_S12);
|
||||
auto actual = kit.toSOLT(p.frequency);
|
||||
p.fe10e32 = S21_through / actual.ThroughS21;
|
||||
p.re23e01 = S12_through / actual.ThroughS12;
|
||||
// All other calibration coefficients to ideal values
|
||||
p.fe30 = 0.0;
|
||||
p.fe22 = 0.0;
|
||||
p.fe00 = 0.0;
|
||||
p.fe11 = 0.0;
|
||||
p.fe10e01 = 1.0;
|
||||
p.re03 = 0.0;
|
||||
p.re11 = 0.0;
|
||||
p.re33 = 0.0;
|
||||
p.re22 = 0.0;
|
||||
p.re23e32 = 1.0;
|
||||
points.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class Tparam {
|
||||
public:
|
||||
Tparam(){};
|
||||
Tparam(T t11, T t12, T t21, T t22)
|
||||
: t11(t11), t12(t12), t21(t21), t22(t22){};
|
||||
void fromSparam(T S11, T S21, T S12, T S22) {
|
||||
t11 = -(S11*S22 - S12*S21) / S21;
|
||||
t12 = S11 / S21;
|
||||
t21 = -S22 / S21;
|
||||
t22 = 1.0 / S21;
|
||||
}
|
||||
void toSparam(T &S11, T &S21, T &S12, T &S22) {
|
||||
S11 = t12 / t22;
|
||||
S21 = T(1) / t22;
|
||||
S12 = (t11*t22 - t12*t21) / t22;
|
||||
S22 = -t21 / t22;
|
||||
}
|
||||
Tparam inverse() {
|
||||
Tparam i;
|
||||
T det = t11*t22 - t12*t21;
|
||||
i.t11 = t22 / det;
|
||||
i.t12 = -t12 / det;
|
||||
i.t21 = -t21 / det;
|
||||
i.t22 = t11 / det;
|
||||
return i;
|
||||
}
|
||||
Tparam operator*(const Tparam &r) {
|
||||
Tparam p;
|
||||
p.t11 = t11*r.t11 + t12*r.t21;
|
||||
p.t12 = t11*r.t12 + t12*r.t22;
|
||||
p.t21 = t21*r.t11 + t22*r.t21;
|
||||
p.t22 = t21*r.t12 + t22*r.t22;
|
||||
return p;
|
||||
}
|
||||
Tparam operator*(const T &r) {
|
||||
Tparam p;
|
||||
p.t11 = t11 * r;
|
||||
p.t12 = t12 * r;
|
||||
p.t21 = t21 * r;
|
||||
p.t22 = t22 * r;
|
||||
return p;
|
||||
}
|
||||
T t11, t12, t21, t22;
|
||||
};
|
||||
|
||||
template<typename T> void solveQuadratic(T a, T b, T c, T &result1, T &result2)
|
||||
{
|
||||
T root = sqrt(b * b - T(4) * a * c);
|
||||
result1 = (-b + root) / (T(2) * a);
|
||||
result2 = (-b - root) / (T(2) * a);
|
||||
}
|
||||
|
||||
void Calibration::constructTRL()
|
||||
{
|
||||
points.clear();
|
||||
for(unsigned int i = 0;i<measurements[Measurement::Through].datapoints.size();i++) {
|
||||
Point p;
|
||||
p.frequency = measurements[Measurement::Through].datapoints[i].frequency;
|
||||
|
||||
// grab raw measurements
|
||||
auto S11_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S11, measurements[Measurement::Through].datapoints[i].imag_S11);
|
||||
auto S21_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S21, measurements[Measurement::Through].datapoints[i].imag_S21);
|
||||
auto S22_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S22, measurements[Measurement::Through].datapoints[i].imag_S22);
|
||||
auto S12_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S12, measurements[Measurement::Through].datapoints[i].imag_S12);
|
||||
auto S11_line = complex<double>(measurements[Measurement::Line].datapoints[i].real_S11, measurements[Measurement::Line].datapoints[i].imag_S11);
|
||||
auto S21_line = complex<double>(measurements[Measurement::Line].datapoints[i].real_S21, measurements[Measurement::Line].datapoints[i].imag_S21);
|
||||
auto S22_line = complex<double>(measurements[Measurement::Line].datapoints[i].real_S22, measurements[Measurement::Line].datapoints[i].imag_S22);
|
||||
auto S12_line = complex<double>(measurements[Measurement::Line].datapoints[i].real_S12, measurements[Measurement::Line].datapoints[i].imag_S12);
|
||||
auto trl = kit.toTRL(p.frequency);
|
||||
complex<double> S11_reflection, S22_reflection;
|
||||
if(trl.reflectionIsNegative) {
|
||||
// used short
|
||||
S11_reflection = complex<double>(measurements[Measurement::Port1Short].datapoints[i].real_S11, measurements[Measurement::Port1Short].datapoints[i].imag_S11);
|
||||
S22_reflection = complex<double>(measurements[Measurement::Port2Short].datapoints[i].real_S22, measurements[Measurement::Port2Short].datapoints[i].imag_S22);
|
||||
} else {
|
||||
// used open
|
||||
S11_reflection = complex<double>(measurements[Measurement::Port1Open].datapoints[i].real_S11, measurements[Measurement::Port1Open].datapoints[i].imag_S11);
|
||||
S22_reflection = complex<double>(measurements[Measurement::Port2Open].datapoints[i].real_S22, measurements[Measurement::Port2Open].datapoints[i].imag_S22);
|
||||
}
|
||||
// calculate TRL calibration
|
||||
// variable names and formulas according to http://emlab.uiuc.edu/ece451/notes/new_TRL.pdf
|
||||
// page 19
|
||||
auto R_T = Tparam<complex<double>>();
|
||||
auto R_D = Tparam<complex<double>>();
|
||||
R_T.fromSparam(S11_through, S21_through, S12_through, S22_through);
|
||||
R_D.fromSparam(S11_line, S21_line, S12_line, S22_line);
|
||||
auto T = R_D*R_T.inverse();
|
||||
complex<double> a_over_c, b;
|
||||
// page 21-22
|
||||
solveQuadratic(T.t21, T.t22 - T.t11, -T.t12, b, a_over_c);
|
||||
// ensure correct root selection
|
||||
// page 23
|
||||
if(abs(b) >= abs(a_over_c)) {
|
||||
swap(b, a_over_c);
|
||||
}
|
||||
// page 24
|
||||
auto g = R_T.t22;
|
||||
auto d = R_T.t11 / g;
|
||||
auto e = R_T.t12 / g;
|
||||
auto f = R_T.t21 / g;
|
||||
|
||||
// page 25
|
||||
auto r22_rho22 = g * (1.0 - e / a_over_c) / (1.0 - b / a_over_c);
|
||||
auto gamma = (f - d / a_over_c) / (1.0 - e / a_over_c);
|
||||
auto beta_over_alpha = (e - b) / (d - b * f);
|
||||
// page 26
|
||||
auto alpha_a = (d - b * f) / (1.0 - e / a_over_c);
|
||||
auto w1 = S11_reflection;
|
||||
auto w2 = S22_reflection;
|
||||
// page 28
|
||||
auto a = sqrt((w1 - b) / (w2 + gamma) * (1.0 + w2 * beta_over_alpha) / (1.0 - w1 / a_over_c) * alpha_a);
|
||||
// page 29, check sign of a
|
||||
auto reflection = (w1 - b) / (a * (1.0 - w1 / a_over_c));
|
||||
if((reflection.real() > 0 && trl.reflectionIsNegative) || (reflection.real() < 0 && !trl.reflectionIsNegative)) {
|
||||
// wrong sign for a
|
||||
a = -a;
|
||||
}
|
||||
// Revert back from error boxes with T parameters to S paramaters,
|
||||
// page 17 + formulas for calculating S parameters from T parameters.
|
||||
// Forward coefficients, normalize for S21 = 1.0 -> r22 = 1.0
|
||||
auto r22 = complex<double>(1.0);
|
||||
auto rho22 = r22_rho22 / r22;
|
||||
auto alpha = alpha_a / a;
|
||||
auto beta = beta_over_alpha * alpha;
|
||||
auto c = a / a_over_c;
|
||||
auto Box_A = Tparam<complex<double>>(r22 * a, r22 * b, r22 * c, r22);
|
||||
auto Box_B = Tparam<complex<double>>(rho22 * alpha, rho22 * beta, rho22 * gamma, rho22);
|
||||
// e00 is S11_A, S11 = T12/T22 = r22*a/r22
|
||||
complex<double> dummy1, dummy2;
|
||||
Box_A.toSparam(p.fe00, dummy1, p.fe10e01, p.fe11);
|
||||
Box_B.toSparam(p.fe22, p.fe10e32, dummy1, dummy2);
|
||||
// no isolation measurement available
|
||||
p.fe30 = 0.0;
|
||||
|
||||
// Reverse coefficients, normalize for S12 = 1.0
|
||||
// => det(T)/T22 = 1.0
|
||||
// => (rho22*alpa*rho22 - rho22*beta*rho*gamma)/rho22 = 1.0
|
||||
// => rho22*alpha - rho22*beta*gamma = 1.0
|
||||
// => rho22 = 1.0/(alpha - beta * gamma)
|
||||
rho22 = 1.0/(alpha - beta * gamma);
|
||||
r22 = r22_rho22 / rho22;
|
||||
|
||||
Box_A = Tparam<complex<double>>(r22 * a, r22 * b, r22 * c, r22);
|
||||
Box_B = Tparam<complex<double>>(rho22 * alpha, rho22 * beta, rho22 * gamma, rho22);
|
||||
Box_A.toSparam(dummy1, dummy2, p.re23e01, p.re11);
|
||||
Box_B.toSparam(p.re22, p.re23e32, dummy1, p.re33);
|
||||
// no isolation measurement available
|
||||
p.re03 = 0.0;
|
||||
|
||||
points.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
void Calibration::correctMeasurement(Protocol::Datapoint &d)
|
||||
{
|
||||
if(type == Type::None) {
|
||||
@ -250,15 +375,17 @@ void Calibration::correctMeasurement(Protocol::Datapoint &d)
|
||||
// find correct entry
|
||||
auto p = getCalibrationPoint(d);
|
||||
|
||||
// equations from page 20 of http://www2.electron.frba.utn.edu.ar/~jcecconi/Bibliografia/04%20-%20Param_S_y_VNA/Network_Analyzer_Error_Models_and_Calibration_Methods.pdf
|
||||
complex<double> S11, S12, S21, S22;
|
||||
|
||||
// equations from page 19 of https://www.rfmentor.com/sites/default/files/NA_Error_Models_and_Cal_Methods.pdf
|
||||
auto denom = (1.0 + (S11m - p.fe00) / p.fe10e01 * p.fe11) * (1.0 + (S22m - p.re33) / p.re23e32 * p.re22)
|
||||
- (S21m - p.fe30) / p.fe10e32 * (S12m - p.re03) / p.re23e01 * p.fe22 * p.re11;
|
||||
auto S11 = ((S11m - p.fe00) / p.fe10e01 * (1.0 + (S22m - p.re33) / p.re23e32 * p.re22)
|
||||
S11 = ((S11m - p.fe00) / p.fe10e01 * (1.0 + (S22m - p.re33) / p.re23e32 * p.re22)
|
||||
- p.fe22 * (S21m - p.fe30) / p.fe10e32 * (S12m - p.re03) / p.re23e01) / denom;
|
||||
auto S21 = ((S21m - p.fe30) / p.fe10e32 * (1.0 + (S22m - p.re33) / p.re23e32 * (p.re22 - p.fe22))) / denom;
|
||||
auto S22 = ((S22m - p.re33) / p.re23e32 * (1.0 + (S11m - p.fe00) / p.fe10e01 * p.fe11)
|
||||
S21 = ((S21m - p.fe30) / p.fe10e32 * (1.0 + (S22m - p.re33) / p.re23e32 * (p.re22 - p.fe22))) / denom;
|
||||
S22 = ((S22m - p.re33) / p.re23e32 * (1.0 + (S11m - p.fe00) / p.fe10e01 * p.fe11)
|
||||
- p.re11 * (S21m - p.fe30) / p.fe10e32 * (S12m - p.re03) / p.re23e01) / denom;
|
||||
auto S12 = ((S12m - p.re03) / p.re23e01 * (1.0 + (S11m - p.fe00) / p.fe10e01 * (p.fe11 - p.re11))) / denom;
|
||||
S12 = ((S12m - p.re03) / p.re23e01 * (1.0 + (S11m - p.fe00) / p.fe10e01 * (p.fe11 - p.re11))) / denom;
|
||||
|
||||
d.real_S11 = S11.real();
|
||||
d.imag_S11 = S11.imag();
|
||||
@ -319,6 +446,8 @@ QString Calibration::MeasurementToString(Calibration::Measurement m)
|
||||
return "Through";
|
||||
case Measurement::Isolation:
|
||||
return "Isolation";
|
||||
case Measurement::Line:
|
||||
return "Line";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@ -330,22 +459,32 @@ QString Calibration::TypeToString(Calibration::Type t)
|
||||
case Type::Port1SOL: return "Port 1"; break;
|
||||
case Type::Port2SOL: return "Port 2"; break;
|
||||
case Type::FullSOLT: return "SOLT"; break;
|
||||
case Type::TransmissionNormalization: return "Normalize"; break;
|
||||
case Type::TRL: return "TRL"; break;
|
||||
default: return "None"; break;
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<Calibration::Type> Calibration::Types()
|
||||
{
|
||||
const std::vector<Calibration::Type> ret = {Type::Port1SOL, Type::Port2SOL, Type::FullSOLT};
|
||||
const std::vector<Calibration::Type> ret = {Type::Port1SOL, Type::Port2SOL, Type::FullSOLT, Type::TransmissionNormalization, Type::TRL};
|
||||
return ret;
|
||||
}
|
||||
|
||||
const std::vector<Calibration::Measurement> Calibration::Measurements(Calibration::Type type)
|
||||
const std::vector<Calibration::Measurement> Calibration::Measurements(Calibration::Type type, bool optional_included)
|
||||
{
|
||||
switch(type) {
|
||||
case Type::FullSOLT:
|
||||
case Type::None:
|
||||
// all possible measurements
|
||||
return {Measurement::Port1Short, Measurement::Port1Open, Measurement::Port1Load,
|
||||
Measurement::Port2Short, Measurement::Port2Open, Measurement::Port2Load,
|
||||
Measurement::Through, Measurement::Isolation, Measurement::Line};
|
||||
case Type::FullSOLT:
|
||||
if(optional_included) {
|
||||
return {Measurement::Port1Short, Measurement::Port1Open, Measurement::Port1Load, Measurement::Port2Short, Measurement::Port2Open, Measurement::Port2Load, Measurement::Through, Measurement::Isolation};
|
||||
} else {
|
||||
return {Measurement::Port1Short, Measurement::Port1Open, Measurement::Port1Load, Measurement::Port2Short, Measurement::Port2Open, Measurement::Port2Load, Measurement::Through};
|
||||
}
|
||||
break;
|
||||
case Type::Port1SOL:
|
||||
return {Measurement::Port1Short, Measurement::Port1Open, Measurement::Port1Load};
|
||||
@ -353,6 +492,16 @@ const std::vector<Calibration::Measurement> Calibration::Measurements(Calibratio
|
||||
case Type::Port2SOL:
|
||||
return {Measurement::Port2Short, Measurement::Port2Open, Measurement::Port2Load};
|
||||
break;
|
||||
case Type::TransmissionNormalization:
|
||||
return {Measurement::Through};
|
||||
break;
|
||||
case Type::TRL:
|
||||
if(kit.isTRLReflectionShort()) {
|
||||
return {Measurement::Through, Measurement::Port1Short, Measurement::Port2Short, Measurement::Line};
|
||||
} else {
|
||||
return {Measurement::Through, Measurement::Port1Open, Measurement::Port2Open, Measurement::Line};
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return {};
|
||||
break;
|
||||
@ -394,6 +543,11 @@ Calibration::MeasurementInfo Calibration::getMeasurementInfo(Calibration::Measur
|
||||
case Measurement::Isolation:
|
||||
info.name = "Isolation";
|
||||
info.prerequisites = "Both ports terminated into 50 ohm";
|
||||
break;
|
||||
case Measurement::Line:
|
||||
info.name = "Line";
|
||||
info.prerequisites = "Port 1 connected to port 2 via line standard";
|
||||
break;
|
||||
}
|
||||
info.points = measurements[m].datapoints.size();
|
||||
if(info.points > 0) {
|
||||
@ -524,7 +678,7 @@ istream& operator >>(istream &in, Calibration &c)
|
||||
{
|
||||
std::string line;
|
||||
while(getline(in, line)) {
|
||||
for(auto m : Calibration::Measurements()) {
|
||||
for(auto m : c.Measurements()) {
|
||||
if(Calibration::MeasurementToString(m) == QString::fromStdString(line)) {
|
||||
// this is the correct measurement
|
||||
c.clearMeasurement(m);
|
||||
@ -561,7 +715,7 @@ istream& operator >>(istream &in, Calibration &c)
|
||||
return in;
|
||||
}
|
||||
|
||||
bool Calibration::SanityCheckSamples(std::vector<Calibration::Measurement> &requiredMeasurements)
|
||||
bool Calibration::SanityCheckSamples(const std::vector<Calibration::Measurement> &requiredMeasurements)
|
||||
{
|
||||
// sanity check measurements, all need to be of the same size with the same frequencies (except for isolation which may be empty)
|
||||
vector<uint64_t> freqs;
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
Port2Load,
|
||||
Isolation,
|
||||
Through,
|
||||
Line,
|
||||
};
|
||||
void clearMeasurements();
|
||||
void clearMeasurement(Measurement type);
|
||||
@ -35,6 +36,8 @@ public:
|
||||
Port1SOL,
|
||||
Port2SOL,
|
||||
FullSOLT,
|
||||
TransmissionNormalization,
|
||||
TRL,
|
||||
None,
|
||||
};
|
||||
|
||||
@ -67,7 +70,7 @@ public:
|
||||
};
|
||||
|
||||
static const std::vector<Type> Types();
|
||||
static const std::vector<Measurement> Measurements(Type type = Type::None);
|
||||
const std::vector<Measurement> Measurements(Type type = Type::None, bool optional_included = true);
|
||||
MeasurementInfo getMeasurementInfo(Measurement m);
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const Calibration& c);
|
||||
@ -89,7 +92,9 @@ private:
|
||||
void construct12TermPoints();
|
||||
void constructPort1SOL();
|
||||
void constructPort2SOL();
|
||||
bool SanityCheckSamples(std::vector<Measurement> &requiredMeasurements);
|
||||
void constructTransmissionNormalization();
|
||||
void constructTRL();
|
||||
bool SanityCheckSamples(const std::vector<Measurement> &requiredMeasurements);
|
||||
class Point
|
||||
{
|
||||
public:
|
||||
|
@ -64,7 +64,9 @@ void CalibrationTraceDialog::on_bOpen_clicked()
|
||||
{
|
||||
cal->openFromFile();
|
||||
UpdateApplyButton();
|
||||
if(cal->getType() != Calibration::Type::None) {
|
||||
emit applyCalibration(cal->getType());
|
||||
}
|
||||
}
|
||||
|
||||
void CalibrationTraceDialog::on_bSave_clicked()
|
||||
|
@ -51,6 +51,12 @@ Calkit::Calkit()
|
||||
load_Sparam = 0;
|
||||
through_Sparam1 = 0;
|
||||
through_Sparam2 = 1;
|
||||
|
||||
TRL_through_Z0 = 50.0;
|
||||
TRL_reflection_short = true;
|
||||
TRL_line_delay = 74;
|
||||
TRL_line_maxfreq = 6000000000;
|
||||
TRL_line_minfreq = 751000000;
|
||||
}
|
||||
|
||||
void Calkit::toFile(std::string filename)
|
||||
@ -75,6 +81,11 @@ void Calkit::toFile(std::string filename)
|
||||
if(through_measurements) {
|
||||
file << through_file << "\n" << through_Sparam1 << "\n" << through_Sparam2 << "\n";
|
||||
}
|
||||
file << TRL_through_Z0 << "\n";
|
||||
file << TRL_reflection_short << "\n";
|
||||
file << TRL_line_delay << "\n";
|
||||
file << TRL_line_minfreq << "\n";
|
||||
file << TRL_line_maxfreq << "\n";
|
||||
file.close();
|
||||
}
|
||||
|
||||
@ -125,6 +136,11 @@ Calkit Calkit::fromFile(std::string filename)
|
||||
file >> c.through_Sparam1;
|
||||
file >> c.through_Sparam2;
|
||||
}
|
||||
file >> c.TRL_through_Z0;
|
||||
file >> c.TRL_reflection_short;
|
||||
file >> c.TRL_line_delay;
|
||||
file >> c.TRL_line_minfreq;
|
||||
file >> c.TRL_line_maxfreq;
|
||||
file.close();
|
||||
return c;
|
||||
}
|
||||
@ -135,10 +151,10 @@ void Calkit::edit()
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
Calkit::Reflection Calkit::toReflection(double frequency)
|
||||
Calkit::SOLT Calkit::toSOLT(double frequency)
|
||||
{
|
||||
fillTouchstoneCache();
|
||||
Reflection ref;
|
||||
SOLT ref;
|
||||
if(load_measurements) {
|
||||
ref.Load = ts_load->interpolate(frequency).S[0];
|
||||
} else {
|
||||
@ -204,8 +220,24 @@ Calkit::Reflection Calkit::toReflection(double frequency)
|
||||
return ref;
|
||||
}
|
||||
|
||||
double Calkit::minFreq()
|
||||
Calkit::TRL Calkit::toTRL(double)
|
||||
{
|
||||
TRL trl;
|
||||
// reflection coefficent sign depends on whether an open or short is used
|
||||
trl.reflectionIsNegative = TRL_reflection_short;
|
||||
// assume ideal through for now
|
||||
trl.ThroughS11 = 0.0;
|
||||
trl.ThroughS12 = 1.0;
|
||||
trl.ThroughS21 = 1.0;
|
||||
trl.ThroughS22 = 0.0;
|
||||
return trl;
|
||||
}
|
||||
|
||||
double Calkit::minFreq(bool TRL)
|
||||
{
|
||||
if(TRL) {
|
||||
return TRL_line_minfreq;
|
||||
} else {
|
||||
fillTouchstoneCache();
|
||||
double min = std::numeric_limits<double>::min();
|
||||
array<Touchstone*, 4> ts_list = {ts_open, ts_short, ts_load, ts_through};
|
||||
@ -220,10 +252,14 @@ double Calkit::minFreq()
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
}
|
||||
|
||||
double Calkit::maxFreq()
|
||||
double Calkit::maxFreq(bool TRL)
|
||||
{
|
||||
if(TRL) {
|
||||
return TRL_line_maxfreq;
|
||||
} else {
|
||||
fillTouchstoneCache();
|
||||
double max = std::numeric_limits<double>::max();
|
||||
array<Touchstone*, 4> ts_list = {ts_open, ts_short, ts_load, ts_through};
|
||||
@ -238,6 +274,12 @@ double Calkit::maxFreq()
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
bool Calkit::isTRLReflectionShort() const
|
||||
{
|
||||
return TRL_reflection_short;
|
||||
}
|
||||
|
||||
void Calkit::clearTouchstoneCache()
|
||||
|
@ -11,7 +11,7 @@ class Calkit
|
||||
public:
|
||||
Calkit();
|
||||
|
||||
class Reflection {
|
||||
class SOLT {
|
||||
public:
|
||||
std::complex<double> Open;
|
||||
std::complex<double> Short;
|
||||
@ -19,13 +19,23 @@ public:
|
||||
std::complex<double> ThroughS11, ThroughS12, ThroughS21, ThroughS22;
|
||||
};
|
||||
|
||||
class TRL {
|
||||
public:
|
||||
bool reflectionIsNegative;
|
||||
std::complex<double> ThroughS11, ThroughS12, ThroughS21, ThroughS22;
|
||||
};
|
||||
|
||||
void toFile(std::string filename);
|
||||
static Calkit fromFile(std::string filename);
|
||||
void edit();
|
||||
Reflection toReflection(double frequency);
|
||||
double minFreq();
|
||||
double maxFreq();
|
||||
SOLT toSOLT(double frequency);
|
||||
TRL toTRL(double frequency);
|
||||
double minFreq(bool TRL = false);
|
||||
double maxFreq(bool TRL = false);
|
||||
bool isTRLReflectionShort() const;
|
||||
|
||||
private:
|
||||
// SOLT standard definitions
|
||||
double open_Z0, open_delay, open_loss, open_C0, open_C1, open_C2, open_C3;
|
||||
double short_Z0, short_delay, short_loss, short_L0, short_L1, short_L2, short_L3;
|
||||
double load_Z0;
|
||||
@ -37,6 +47,13 @@ private:
|
||||
bool load_measurements;
|
||||
bool through_measurements;
|
||||
|
||||
// TRL standard definitions
|
||||
double TRL_through_Z0;
|
||||
bool TRL_reflection_short;
|
||||
double TRL_line_delay;
|
||||
double TRL_line_minfreq;
|
||||
double TRL_line_maxfreq;
|
||||
|
||||
std::string open_file, short_file, load_file, through_file;
|
||||
int open_Sparam, short_Sparam, load_Sparam, through_Sparam1, through_Sparam2;
|
||||
|
||||
|
@ -38,10 +38,30 @@ CalkitDialog::CalkitDialog(Calkit &c, QWidget *parent) :
|
||||
ui->load_touchstone->setPorts(1);
|
||||
ui->through_touchstone->setPorts(2);
|
||||
|
||||
ui->TRL_line_max->setUnit("Hz");
|
||||
ui->TRL_line_max->setPrecision(4);
|
||||
ui->TRL_line_max->setPrefixes(" kMG");
|
||||
ui->TRL_line_min->setUnit("Hz");
|
||||
ui->TRL_line_min->setPrecision(4);
|
||||
ui->TRL_line_min->setPrefixes(" kMG");
|
||||
|
||||
editKit.clearTouchstoneCache();
|
||||
ownKit = editKit;
|
||||
updateEntries();
|
||||
|
||||
connect(ui->TRL_line_min, &SIUnitEdit::valueChanged, [=](double newval){
|
||||
ownKit.TRL_line_minfreq = newval;
|
||||
updateEntries();
|
||||
});
|
||||
connect(ui->TRL_line_max, &SIUnitEdit::valueChanged, [=](double newval){
|
||||
ownKit.TRL_line_maxfreq = newval;
|
||||
updateEntries();
|
||||
});
|
||||
connect(ui->TRL_line_delay, &QLineEdit::editingFinished, [=](){
|
||||
ownKit.TRL_line_delay = ui->TRL_line_delay->text().toDouble();
|
||||
updateEntries();
|
||||
});
|
||||
|
||||
auto UpdateStatus = [=]() {
|
||||
bool ok = true;
|
||||
if(ui->open_measurement->isChecked() && !ui->open_touchstone->getStatus()) {
|
||||
@ -110,7 +130,6 @@ CalkitDialog::~CalkitDialog()
|
||||
|
||||
void CalkitDialog::parseEntries()
|
||||
{
|
||||
|
||||
// type
|
||||
ownKit.open_measurements = ui->open_measurement->isChecked();
|
||||
ownKit.short_measurements = ui->short_measurement->isChecked();
|
||||
@ -151,6 +170,13 @@ void CalkitDialog::parseEntries()
|
||||
ownKit.load_Sparam = ui->load_touchstone->getPorts()[0];
|
||||
ownKit.through_Sparam1 = ui->through_touchstone->getPorts()[0];
|
||||
ownKit.through_Sparam2 = ui->through_touchstone->getPorts()[1];
|
||||
|
||||
// TRL
|
||||
ownKit.TRL_through_Z0 = ui->TRL_through_Z0->text().toDouble();
|
||||
ownKit.TRL_reflection_short = ui->TRL_R_short->isChecked();
|
||||
ownKit.TRL_line_delay = ui->TRL_line_delay->text().toDouble();
|
||||
ownKit.TRL_line_minfreq = ui->TRL_line_min->value();
|
||||
ownKit.TRL_line_maxfreq = ui->TRL_line_max->value();
|
||||
}
|
||||
|
||||
void CalkitDialog::updateEntries()
|
||||
@ -216,4 +242,25 @@ void CalkitDialog::updateEntries()
|
||||
} else {
|
||||
ui->through_coefficients->click();
|
||||
}
|
||||
|
||||
// TRL
|
||||
ui->TRL_through_Z0->setText(QString::number(ownKit.TRL_through_Z0));
|
||||
if(ownKit.TRL_reflection_short) {
|
||||
ui->TRL_R_short->setChecked(true);
|
||||
} else {
|
||||
ui->TRL_R_open->setChecked(true);
|
||||
}
|
||||
ui->TRL_line_delay->setText(QString::number(ownKit.TRL_line_delay));
|
||||
ui->TRL_line_min->setValueQuiet(ownKit.TRL_line_minfreq);
|
||||
ui->TRL_line_max->setValueQuiet(ownKit.TRL_line_maxfreq);
|
||||
// Check if line length is appropriate for frequencies
|
||||
auto minDelay = 20.0/(ownKit.TRL_line_minfreq * 360.0) * 1e12;
|
||||
auto maxDelay = 160.0/(ownKit.TRL_line_maxfreq * 360.0) * 1e12;
|
||||
if(ownKit.TRL_line_delay < minDelay) {
|
||||
ui->TRL_line_warning->setText("Line too short, minimum required delay is "+QString::number(minDelay, 'g', 3) + "ps");
|
||||
} else if(ownKit.TRL_line_delay > maxDelay) {
|
||||
ui->TRL_line_warning->setText("Line too long, maximum allowed delay is "+QString::number(maxDelay, 'g', 3) + "ps");
|
||||
} else {
|
||||
ui->TRL_line_warning->clear();
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1121</width>
|
||||
<height>345</height>
|
||||
<width>1141</width>
|
||||
<height>394</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -30,149 +30,15 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_17">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="open_coefficients">
|
||||
<property name="text">
|
||||
<string>Coefficients</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">OpenType</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="open_measurement">
|
||||
<property name="text">
|
||||
<string>Measurement file</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">OpenType</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="open_stack">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Offset delay [ps]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="open_delay"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Offset loss [GΩ/s]: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="open_loss"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>C0 [10<sup>-15</sup>F]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="open_C0"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>C1 [10<sup>-27</sup>F/Hz]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="open_C1"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>C2 [10<sup>-36</sup>F/Hz<sup>2</sup>]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="open_C2"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>C0 [10<sup>-45</sup>F/Hz<sup>3</sup>]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="open_C3"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="open_Z0"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Z0 [Ω]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0">
|
||||
<item>
|
||||
<widget class="TouchstoneImport" name="open_touchstone" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>SOLT</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
@ -284,7 +150,11 @@
|
||||
<widget class="QLineEdit" name="short_L3"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="short_Z0"/>
|
||||
<widget class="QLineEdit" name="short_Z0">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
@ -308,6 +178,152 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="open_coefficients">
|
||||
<property name="text">
|
||||
<string>Coefficients</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">OpenType</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="open_measurement">
|
||||
<property name="text">
|
||||
<string>Measurement file</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">OpenType</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="open_stack">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Offset delay [ps]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="open_delay"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Offset loss [GΩ/s]: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="open_loss"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>C0 [10<sup>-15</sup>F]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="open_C0"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>C1 [10<sup>-27</sup>F/Hz]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="open_C1"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>C2 [10<sup>-36</sup>F/Hz<sup>2</sup>]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="open_C2"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>C0 [10<sup>-45</sup>F/Hz<sup>3</sup>]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="open_C3"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="open_Z0">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Z0 [Ω]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0">
|
||||
<item>
|
||||
<widget class="TouchstoneImport" name="open_touchstone" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
@ -373,7 +389,11 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="load_Z0"/>
|
||||
<widget class="QLineEdit" name="load_Z0">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@ -455,7 +475,11 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="through_Z0"/>
|
||||
<widget class="QLineEdit" name="through_Z0">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_21">
|
||||
@ -493,6 +517,287 @@
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>TRL</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="1,0,1,0,1,0">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_23">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Through</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_36">
|
||||
<property name="text">
|
||||
<string>Z0 [Ω]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="TRL_through_Z0">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_24">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reflection</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="TRL_R_short">
|
||||
<property name="text">
|
||||
<string>Short</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">TRL_Rtype</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="TRL_R_open">
|
||||
<property name="text">
|
||||
<string>Open</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">TRL_Rtype</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Line</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_6">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_37">
|
||||
<property name="text">
|
||||
<string>Delay [ps]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="TRL_line_delay">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_38">
|
||||
<property name="text">
|
||||
<string>Min. frequency:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="SIUnitEdit" name="TRL_line_min">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_39">
|
||||
<property name="text">
|
||||
<string>Max. frequency:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="SIUnitEdit" name="TRL_line_max">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="TRL_line_warning">
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>239</red>
|
||||
<green>41</green>
|
||||
<blue>41</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>239</red>
|
||||
<green>41</green>
|
||||
<blue>41</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>190</red>
|
||||
<green>190</green>
|
||||
<blue>190</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
@ -516,6 +821,11 @@
|
||||
<header>CustomWidgets/touchstoneimport.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>SIUnitEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>CustomWidgets/siunitedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>open_Z0</tabstop>
|
||||
@ -594,8 +904,9 @@
|
||||
</connections>
|
||||
<buttongroups>
|
||||
<buttongroup name="LoadType"/>
|
||||
<buttongroup name="OpenType"/>
|
||||
<buttongroup name="ShortType"/>
|
||||
<buttongroup name="OpenType"/>
|
||||
<buttongroup name="ThroughType"/>
|
||||
<buttongroup name="TRL_Rtype"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
|
@ -53,7 +53,6 @@ QVariant MeasurementModel::data(const QModelIndex &index, int role) const
|
||||
case ColIndexDescription: return 500; break;
|
||||
case ColIndexData: return 300; break;
|
||||
case ColIndexDate: return 300; break;
|
||||
case ColIndexStatusSymbol: return 150; break;
|
||||
default: return QVariant(); break;
|
||||
}
|
||||
}
|
||||
@ -69,7 +68,6 @@ QVariant MeasurementModel::headerData(int section, Qt::Orientation orientation,
|
||||
case ColIndexDescription: return "Prerequisites"; break;
|
||||
case ColIndexData: return "Statistics"; break;
|
||||
case ColIndexDate: return "Timestamp"; break;
|
||||
case ColIndexStatusSymbol: return "Status"; break;
|
||||
default: return QVariant(); break;
|
||||
}
|
||||
} else {
|
||||
|
@ -26,7 +26,6 @@ private:
|
||||
ColIndexDescription,
|
||||
ColIndexData,
|
||||
ColIndexDate,
|
||||
ColIndexStatusSymbol,
|
||||
ColIndexLast
|
||||
};
|
||||
Calibration *cal;
|
||||
|
@ -702,10 +702,11 @@ void VNA::ApplyCalibration(Calibration::Type type)
|
||||
{
|
||||
if(cal.calculationPossible(type)) {
|
||||
try {
|
||||
cal.constructErrorTerms(type);
|
||||
if(cal.constructErrorTerms(type)) {
|
||||
calValid = true;
|
||||
average.reset();
|
||||
emit CalibrationApplied(type);
|
||||
}
|
||||
} catch (runtime_error e) {
|
||||
QMessageBox::critical(this, "Calibration failure", e.what());
|
||||
DisableCalibration(true);
|
||||
|
Loading…
Reference in New Issue
Block a user