Impedance renormalization moved to de-embedding
This commit is contained in:
parent
d08388f903
commit
4307a392fb
@ -15,15 +15,15 @@ using namespace std;
|
|||||||
Calibration::Calibration()
|
Calibration::Calibration()
|
||||||
{
|
{
|
||||||
// Create vectors for measurements
|
// Create vectors for measurements
|
||||||
measurements[Measurement::Port1Open].datapoints = vector<Protocol::Datapoint>();
|
measurements[Measurement::Port1Open].datapoints = vector<VNAData>();
|
||||||
measurements[Measurement::Port1Short].datapoints = vector<Protocol::Datapoint>();
|
measurements[Measurement::Port1Short].datapoints = vector<VNAData>();
|
||||||
measurements[Measurement::Port1Load].datapoints = vector<Protocol::Datapoint>();
|
measurements[Measurement::Port1Load].datapoints = vector<VNAData>();
|
||||||
measurements[Measurement::Port2Open].datapoints = vector<Protocol::Datapoint>();
|
measurements[Measurement::Port2Open].datapoints = vector<VNAData>();
|
||||||
measurements[Measurement::Port2Short].datapoints = vector<Protocol::Datapoint>();
|
measurements[Measurement::Port2Short].datapoints = vector<VNAData>();
|
||||||
measurements[Measurement::Port2Load].datapoints = vector<Protocol::Datapoint>();
|
measurements[Measurement::Port2Load].datapoints = vector<VNAData>();
|
||||||
measurements[Measurement::Isolation].datapoints = vector<Protocol::Datapoint>();
|
measurements[Measurement::Isolation].datapoints = vector<VNAData>();
|
||||||
measurements[Measurement::Through].datapoints = vector<Protocol::Datapoint>();
|
measurements[Measurement::Through].datapoints = vector<VNAData>();
|
||||||
measurements[Measurement::Line].datapoints = vector<Protocol::Datapoint>();
|
measurements[Measurement::Line].datapoints = vector<VNAData>();
|
||||||
|
|
||||||
type = Type::None;
|
type = Type::None;
|
||||||
port1Standard = port2Standard = PortStandard::Male;
|
port1Standard = port2Standard = PortStandard::Male;
|
||||||
@ -84,13 +84,13 @@ void Calibration::clearMeasurement(Calibration::Measurement type)
|
|||||||
qDebug() << "Deleted" << MeasurementToString(type) << "measurement";
|
qDebug() << "Deleted" << MeasurementToString(type) << "measurement";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Calibration::addMeasurement(Calibration::Measurement type, Protocol::Datapoint &d)
|
void Calibration::addMeasurement(Calibration::Measurement type, VNAData &d)
|
||||||
{
|
{
|
||||||
measurements[type].datapoints.push_back(d);
|
measurements[type].datapoints.push_back(d);
|
||||||
measurements[type].timestamp = QDateTime::currentDateTime();
|
measurements[type].timestamp = QDateTime::currentDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Calibration::addMeasurements(std::set<Calibration::Measurement> types, Protocol::Datapoint &d)
|
void Calibration::addMeasurements(std::set<Calibration::Measurement> types, VNAData &d)
|
||||||
{
|
{
|
||||||
for(auto t : types) {
|
for(auto t : types) {
|
||||||
addMeasurement(t, d);
|
addMeasurement(t, d);
|
||||||
@ -176,22 +176,22 @@ void Calibration::construct12TermPoints()
|
|||||||
Point p;
|
Point p;
|
||||||
p.frequency = measurements[Measurement::Port1Open].datapoints[i].frequency;
|
p.frequency = measurements[Measurement::Port1Open].datapoints[i].frequency;
|
||||||
// extract required complex reflection/transmission factors from datapoints
|
// extract required complex reflection/transmission factors from datapoints
|
||||||
auto S11_open = complex<double>(measurements[Measurement::Port1Open].datapoints[i].real_S11, measurements[Measurement::Port1Open].datapoints[i].imag_S11);
|
auto S11_open = measurements[Measurement::Port1Open].datapoints[i].S.m11;
|
||||||
auto S11_short = complex<double>(measurements[Measurement::Port1Short].datapoints[i].real_S11, measurements[Measurement::Port1Short].datapoints[i].imag_S11);
|
auto S11_short = measurements[Measurement::Port1Short].datapoints[i].S.m11;
|
||||||
auto S11_load = complex<double>(measurements[Measurement::Port1Load].datapoints[i].real_S11, measurements[Measurement::Port1Load].datapoints[i].imag_S11);
|
auto S11_load = measurements[Measurement::Port1Load].datapoints[i].S.m11;
|
||||||
auto S22_open = complex<double>(measurements[Measurement::Port2Open].datapoints[i].real_S22, measurements[Measurement::Port2Open].datapoints[i].imag_S22);
|
auto S22_open = measurements[Measurement::Port2Open].datapoints[i].S.m22;
|
||||||
auto S22_short = complex<double>(measurements[Measurement::Port2Short].datapoints[i].real_S22, measurements[Measurement::Port2Short].datapoints[i].imag_S22);
|
auto S22_short = measurements[Measurement::Port2Short].datapoints[i].S.m22;
|
||||||
auto S22_load = complex<double>(measurements[Measurement::Port2Load].datapoints[i].real_S22, measurements[Measurement::Port2Load].datapoints[i].imag_S22);
|
auto S22_load = measurements[Measurement::Port2Load].datapoints[i].S.m22;
|
||||||
auto S21_isolation = complex<double>(0,0);
|
auto S21_isolation = complex<double>(0,0);
|
||||||
auto S12_isolation = complex<double>(0,0);
|
auto S12_isolation = complex<double>(0,0);
|
||||||
if(isolation_measured) {
|
if(isolation_measured) {
|
||||||
S21_isolation = complex<double>(measurements[Measurement::Isolation].datapoints[i].real_S21, measurements[Measurement::Isolation].datapoints[i].imag_S21);
|
S21_isolation = measurements[Measurement::Isolation].datapoints[i].S.m21;
|
||||||
S12_isolation = complex<double>(measurements[Measurement::Isolation].datapoints[i].real_S12, measurements[Measurement::Isolation].datapoints[i].imag_S12);
|
S12_isolation = measurements[Measurement::Isolation].datapoints[i].S.m12;
|
||||||
}
|
}
|
||||||
auto S11_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S11, measurements[Measurement::Through].datapoints[i].imag_S11);
|
auto S11_through = measurements[Measurement::Through].datapoints[i].S.m11;
|
||||||
auto S21_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S21, measurements[Measurement::Through].datapoints[i].imag_S21);
|
auto S21_through = measurements[Measurement::Through].datapoints[i].S.m21;
|
||||||
auto S22_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S22, measurements[Measurement::Through].datapoints[i].imag_S22);
|
auto S22_through = measurements[Measurement::Through].datapoints[i].S.m22;
|
||||||
auto S12_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S12, measurements[Measurement::Through].datapoints[i].imag_S12);
|
auto S12_through = measurements[Measurement::Through].datapoints[i].S.m12;
|
||||||
|
|
||||||
auto actual = kit.toSOLT(p.frequency, port1Standard == PortStandard::Male);
|
auto actual = kit.toSOLT(p.frequency, port1Standard == PortStandard::Male);
|
||||||
// Forward calibration
|
// Forward calibration
|
||||||
@ -232,9 +232,9 @@ void Calibration::constructPort1SOL()
|
|||||||
Point p;
|
Point p;
|
||||||
p.frequency = measurements[Measurement::Port1Open].datapoints[i].frequency;
|
p.frequency = measurements[Measurement::Port1Open].datapoints[i].frequency;
|
||||||
// extract required complex reflection/transmission factors from datapoints
|
// extract required complex reflection/transmission factors from datapoints
|
||||||
auto S11_open = complex<double>(measurements[Measurement::Port1Open].datapoints[i].real_S11, measurements[Measurement::Port1Open].datapoints[i].imag_S11);
|
auto S11_open = measurements[Measurement::Port1Open].datapoints[i].S.m11;
|
||||||
auto S11_short = complex<double>(measurements[Measurement::Port1Short].datapoints[i].real_S11, measurements[Measurement::Port1Short].datapoints[i].imag_S11);
|
auto S11_short = measurements[Measurement::Port1Short].datapoints[i].S.m11;
|
||||||
auto S11_load = complex<double>(measurements[Measurement::Port1Load].datapoints[i].real_S11, measurements[Measurement::Port1Load].datapoints[i].imag_S11);
|
auto S11_load = measurements[Measurement::Port1Load].datapoints[i].S.m11;
|
||||||
// OSL port1
|
// OSL port1
|
||||||
auto actual = kit.toSOLT(p.frequency, port1Standard == PortStandard::Male);
|
auto actual = kit.toSOLT(p.frequency, port1Standard == PortStandard::Male);
|
||||||
// See page 13 of https://www.rfmentor.com/sites/default/files/NA_Error_Models_and_Cal_Methods.pdf
|
// See page 13 of https://www.rfmentor.com/sites/default/files/NA_Error_Models_and_Cal_Methods.pdf
|
||||||
@ -262,9 +262,9 @@ void Calibration::constructPort2SOL()
|
|||||||
Point p;
|
Point p;
|
||||||
p.frequency = measurements[Measurement::Port2Open].datapoints[i].frequency;
|
p.frequency = measurements[Measurement::Port2Open].datapoints[i].frequency;
|
||||||
// extract required complex reflection/transmission factors from datapoints
|
// extract required complex reflection/transmission factors from datapoints
|
||||||
auto S22_open = complex<double>(measurements[Measurement::Port2Open].datapoints[i].real_S22, measurements[Measurement::Port2Open].datapoints[i].imag_S22);
|
auto S22_open = measurements[Measurement::Port2Open].datapoints[i].S.m22;
|
||||||
auto S22_short = complex<double>(measurements[Measurement::Port2Short].datapoints[i].real_S22, measurements[Measurement::Port2Short].datapoints[i].imag_S22);
|
auto S22_short = measurements[Measurement::Port2Short].datapoints[i].S.m22;
|
||||||
auto S22_load = complex<double>(measurements[Measurement::Port2Load].datapoints[i].real_S22, measurements[Measurement::Port2Load].datapoints[i].imag_S22);
|
auto S22_load = measurements[Measurement::Port2Load].datapoints[i].S.m22;
|
||||||
// OSL port2
|
// OSL port2
|
||||||
auto actual = kit.toSOLT(p.frequency, port1Standard == PortStandard::Male);
|
auto actual = kit.toSOLT(p.frequency, port1Standard == PortStandard::Male);
|
||||||
// See page 19 of https://www.rfmentor.com/sites/default/files/NA_Error_Models_and_Cal_Methods.pdf
|
// See page 19 of https://www.rfmentor.com/sites/default/files/NA_Error_Models_and_Cal_Methods.pdf
|
||||||
@ -292,8 +292,8 @@ void Calibration::constructTransmissionNormalization()
|
|||||||
Point p;
|
Point p;
|
||||||
p.frequency = measurements[Measurement::Through].datapoints[i].frequency;
|
p.frequency = measurements[Measurement::Through].datapoints[i].frequency;
|
||||||
// extract required complex reflection/transmission factors from datapoints
|
// 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 S21_through = measurements[Measurement::Through].datapoints[i].S.m21;
|
||||||
auto S12_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S12, measurements[Measurement::Through].datapoints[i].imag_S12);
|
auto S12_through = measurements[Measurement::Through].datapoints[i].S.m12;
|
||||||
auto actual = kit.toSOLT(p.frequency);
|
auto actual = kit.toSOLT(p.frequency);
|
||||||
p.fe10e32 = S21_through / actual.ThroughS21;
|
p.fe10e32 = S21_through / actual.ThroughS21;
|
||||||
p.re23e01 = S12_through / actual.ThroughS12;
|
p.re23e01 = S12_through / actual.ThroughS12;
|
||||||
@ -329,24 +329,24 @@ void Calibration::constructTRL()
|
|||||||
p.frequency = measurements[Measurement::Through].datapoints[i].frequency;
|
p.frequency = measurements[Measurement::Through].datapoints[i].frequency;
|
||||||
|
|
||||||
// grab raw measurements
|
// grab raw measurements
|
||||||
auto S11_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S11, measurements[Measurement::Through].datapoints[i].imag_S11);
|
auto S11_through = measurements[Measurement::Through].datapoints[i].S.m11;
|
||||||
auto S21_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S21, measurements[Measurement::Through].datapoints[i].imag_S21);
|
auto S21_through = measurements[Measurement::Through].datapoints[i].S.m21;
|
||||||
auto S22_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S22, measurements[Measurement::Through].datapoints[i].imag_S22);
|
auto S22_through = measurements[Measurement::Through].datapoints[i].S.m22;
|
||||||
auto S12_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S12, measurements[Measurement::Through].datapoints[i].imag_S12);
|
auto S12_through = measurements[Measurement::Through].datapoints[i].S.m12;
|
||||||
auto S11_line = complex<double>(measurements[Measurement::Line].datapoints[i].real_S11, measurements[Measurement::Line].datapoints[i].imag_S11);
|
auto S11_line = measurements[Measurement::Line].datapoints[i].S.m11;
|
||||||
auto S21_line = complex<double>(measurements[Measurement::Line].datapoints[i].real_S21, measurements[Measurement::Line].datapoints[i].imag_S21);
|
auto S21_line = measurements[Measurement::Line].datapoints[i].S.m21;
|
||||||
auto S22_line = complex<double>(measurements[Measurement::Line].datapoints[i].real_S22, measurements[Measurement::Line].datapoints[i].imag_S22);
|
auto S22_line = measurements[Measurement::Line].datapoints[i].S.m22;
|
||||||
auto S12_line = complex<double>(measurements[Measurement::Line].datapoints[i].real_S12, measurements[Measurement::Line].datapoints[i].imag_S12);
|
auto S12_line = measurements[Measurement::Line].datapoints[i].S.m12;
|
||||||
auto trl = kit.toTRL(p.frequency);
|
auto trl = kit.toTRL(p.frequency);
|
||||||
complex<double> S11_reflection, S22_reflection;
|
complex<double> S11_reflection, S22_reflection;
|
||||||
if(trl.reflectionIsNegative) {
|
if(trl.reflectionIsNegative) {
|
||||||
// used short
|
// used short
|
||||||
S11_reflection = complex<double>(measurements[Measurement::Port1Short].datapoints[i].real_S11, measurements[Measurement::Port1Short].datapoints[i].imag_S11);
|
S11_reflection = measurements[Measurement::Port1Short].datapoints[i].S.m11;
|
||||||
S22_reflection = complex<double>(measurements[Measurement::Port2Short].datapoints[i].real_S22, measurements[Measurement::Port2Short].datapoints[i].imag_S22);
|
S22_reflection = measurements[Measurement::Port2Short].datapoints[i].S.m22;
|
||||||
} else {
|
} else {
|
||||||
// used open
|
// used open
|
||||||
S11_reflection = complex<double>(measurements[Measurement::Port1Open].datapoints[i].real_S11, measurements[Measurement::Port1Open].datapoints[i].imag_S11);
|
S11_reflection = measurements[Measurement::Port1Open].datapoints[i].S.m11;
|
||||||
S22_reflection = complex<double>(measurements[Measurement::Port2Open].datapoints[i].real_S22, measurements[Measurement::Port2Open].datapoints[i].imag_S22);
|
S22_reflection = measurements[Measurement::Port2Open].datapoints[i].S.m22;
|
||||||
}
|
}
|
||||||
// calculate TRL calibration
|
// calculate TRL calibration
|
||||||
// variable names and formulas according to http://emlab.uiuc.edu/ece451/notes/new_TRL.pdf
|
// variable names and formulas according to http://emlab.uiuc.edu/ece451/notes/new_TRL.pdf
|
||||||
@ -432,17 +432,17 @@ void Calibration::constructTRL()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Calibration::correctMeasurement(Protocol::Datapoint &d)
|
void Calibration::correctMeasurement(VNAData &d)
|
||||||
{
|
{
|
||||||
if(type == Type::None) {
|
if(type == Type::None) {
|
||||||
// No calibration data, do nothing
|
// No calibration data, do nothing
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Convert measurements to complex variables
|
// Convert measurements to complex variables
|
||||||
auto S11m = complex<double>(d.real_S11, d.imag_S11);
|
auto S11m = d.S.m11;
|
||||||
auto S21m = complex<double>(d.real_S21, d.imag_S21);
|
auto S21m = d.S.m21;
|
||||||
auto S22m = complex<double>(d.real_S22, d.imag_S22);
|
auto S22m = d.S.m22;
|
||||||
auto S12m = complex<double>(d.real_S12, d.imag_S12);
|
auto S12m = d.S.m12;
|
||||||
|
|
||||||
// find correct entry
|
// find correct entry
|
||||||
auto p = getCalibrationPoint(d);
|
auto p = getCalibrationPoint(d);
|
||||||
@ -459,14 +459,7 @@ void Calibration::correctMeasurement(Protocol::Datapoint &d)
|
|||||||
- p.re11 * (S21m - p.fe30) / p.fe10e32 * (S12m - p.re03) / p.re23e01) / denom;
|
- p.re11 * (S21m - p.fe30) / p.fe10e32 * (S12m - p.re03) / p.re23e01) / denom;
|
||||||
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.S = Sparam(S11, S12, S21, S22);
|
||||||
d.imag_S11 = S11.imag();
|
|
||||||
d.real_S12 = S12.real();
|
|
||||||
d.imag_S12 = S12.imag();
|
|
||||||
d.real_S21 = S21.real();
|
|
||||||
d.imag_S21 = S21.imag();
|
|
||||||
d.real_S22 = S22.real();
|
|
||||||
d.imag_S22 = S22.imag();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Calibration::correctTraces(Trace &S11, Trace &S12, Trace &S21, Trace &S22)
|
void Calibration::correctTraces(Trace &S11, Trace &S12, Trace &S21, Trace &S22)
|
||||||
@ -741,13 +734,13 @@ std::vector<Trace *> Calibration::getMeasurementTraces()
|
|||||||
Trace::Data d;
|
Trace::Data d;
|
||||||
d.x = p.frequency;
|
d.x = p.frequency;
|
||||||
if(prefix == "S11") {
|
if(prefix == "S11") {
|
||||||
d.y = complex<double>(p.real_S11, p.imag_S11);
|
d.y = p.S.m11;
|
||||||
} else if(prefix == "S12") {
|
} else if(prefix == "S12") {
|
||||||
d.y = complex<double>(p.real_S12, p.imag_S12);
|
d.y = p.S.m12;
|
||||||
} else if(prefix == "S21") {
|
} else if(prefix == "S21") {
|
||||||
d.y = complex<double>(p.real_S21, p.imag_S21);
|
d.y = p.S.m21;
|
||||||
} else {
|
} else {
|
||||||
d.y = complex<double>(p.real_S22, p.imag_S22);
|
d.y = p.S.m22;
|
||||||
}
|
}
|
||||||
t->addData(d, TraceMath::DataType::Frequency);
|
t->addData(d, TraceMath::DataType::Frequency);
|
||||||
}
|
}
|
||||||
@ -916,14 +909,14 @@ nlohmann::json Calibration::toJSON()
|
|||||||
for(auto p : m.second.datapoints) {
|
for(auto p : m.second.datapoints) {
|
||||||
nlohmann::json j_point;
|
nlohmann::json j_point;
|
||||||
j_point["frequency"] = p.frequency;
|
j_point["frequency"] = p.frequency;
|
||||||
j_point["S11_real"] = p.real_S11;
|
j_point["S11_real"] = p.S.m11.real();
|
||||||
j_point["S11_imag"] = p.imag_S11;
|
j_point["S11_imag"] = p.S.m11.imag();
|
||||||
j_point["S12_real"] = p.real_S12;
|
j_point["S12_real"] = p.S.m12.real();
|
||||||
j_point["S12_imag"] = p.imag_S12;
|
j_point["S12_imag"] = p.S.m12.imag();
|
||||||
j_point["S21_real"] = p.real_S21;
|
j_point["S21_real"] = p.S.m21.real();
|
||||||
j_point["S21_imag"] = p.imag_S21;
|
j_point["S21_imag"] = p.S.m21.imag();
|
||||||
j_point["S22_real"] = p.real_S22;
|
j_point["S22_real"] = p.S.m22.real();
|
||||||
j_point["S22_imag"] = p.imag_S22;
|
j_point["S22_imag"] = p.S.m22.imag();
|
||||||
j_points.push_back(j_point);
|
j_points.push_back(j_point);
|
||||||
}
|
}
|
||||||
j_measurement["points"] = j_points;
|
j_measurement["points"] = j_points;
|
||||||
@ -964,17 +957,13 @@ void Calibration::fromJSON(nlohmann::json j)
|
|||||||
}
|
}
|
||||||
int pointNum = 0;
|
int pointNum = 0;
|
||||||
for(auto j_p : j_m["points"]) {
|
for(auto j_p : j_m["points"]) {
|
||||||
Protocol::Datapoint p;
|
VNAData p;
|
||||||
p.pointNum = pointNum++;
|
p.pointNum = pointNum++;
|
||||||
p.frequency = j_p.value("frequency", 0.0);
|
p.frequency = j_p.value("frequency", 0.0);
|
||||||
p.real_S11 = j_p.value("S11_real", 0.0);
|
p.S.m11 = complex<double>(j_p.value("S11_real", 0.0), j_p.value("S11_imag", 0.0));
|
||||||
p.imag_S11 = j_p.value("S11_imag", 0.0);
|
p.S.m12 = complex<double>(j_p.value("S12_real", 0.0), j_p.value("S12_imag", 0.0));
|
||||||
p.real_S12 = j_p.value("S12_real", 0.0);
|
p.S.m21 = complex<double>(j_p.value("S21_real", 0.0), j_p.value("S21_imag", 0.0));
|
||||||
p.imag_S12 = j_p.value("S12_imag", 0.0);
|
p.S.m22 = complex<double>(j_p.value("S22_real", 0.0), j_p.value("S22_imag", 0.0));
|
||||||
p.real_S21 = j_p.value("S21_real", 0.0);
|
|
||||||
p.imag_S21 = j_p.value("S21_imag", 0.0);
|
|
||||||
p.real_S22 = j_p.value("S22_real", 0.0);
|
|
||||||
p.imag_S22 = j_p.value("S22_imag", 0.0);
|
|
||||||
measurements[m].datapoints.push_back(p);
|
measurements[m].datapoints.push_back(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -997,24 +986,6 @@ QString Calibration::getCurrentCalibrationFile(){
|
|||||||
return this->currentCalFile;
|
return this->currentCalFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream& operator<<(ostream &os, const Calibration &c)
|
|
||||||
{
|
|
||||||
for(auto m : c.measurements) {
|
|
||||||
if(m.second.datapoints.size() > 0) {
|
|
||||||
os << c.MeasurementToString(m.first).toStdString() << endl;
|
|
||||||
os << m.second.timestamp.toSecsSinceEpoch() << endl;
|
|
||||||
os << m.second.datapoints.size() << endl;
|
|
||||||
for(auto p : m.second.datapoints) {
|
|
||||||
os << p.pointNum << " " << p.frequency << " ";
|
|
||||||
os << p.imag_S11 << " " << p.real_S11 << " " << p.imag_S21 << " " << p.real_S21 << " " << p.imag_S12 << " " << p.real_S12 << " " << p.imag_S22 << " " << p.real_S22;
|
|
||||||
os << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
os << Calibration::TypeToString(c.getType()).toStdString() << endl;
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
istream& operator >>(istream &in, Calibration &c)
|
istream& operator >>(istream &in, Calibration &c)
|
||||||
{
|
{
|
||||||
// old file format did not contain port standard gender, set default
|
// old file format did not contain port standard gender, set default
|
||||||
@ -1039,7 +1010,7 @@ istream& operator >>(istream &in, Calibration &c)
|
|||||||
Protocol::Datapoint p;
|
Protocol::Datapoint p;
|
||||||
in >> p.pointNum >> p.frequency;
|
in >> p.pointNum >> p.frequency;
|
||||||
in >> p.imag_S11 >> p.real_S11 >> p.imag_S21 >> p.real_S21 >> p.imag_S12 >> p.real_S12 >> p.imag_S22 >> p.real_S22;
|
in >> p.imag_S11 >> p.real_S11 >> p.imag_S21 >> p.real_S21 >> p.imag_S12 >> p.real_S12 >> p.imag_S22 >> p.real_S22;
|
||||||
c.measurements[m].datapoints.push_back(p);
|
c.measurements[m].datapoints.push_back(VNAData(p));
|
||||||
if(in.eof() || in.bad() || in.fail()) {
|
if(in.eof() || in.bad() || in.fail()) {
|
||||||
c.clearMeasurement(m);
|
c.clearMeasurement(m);
|
||||||
throw runtime_error("Failed to parse measurement \"" + line + "\", aborting calibration data import.");
|
throw runtime_error("Failed to parse measurement \"" + line + "\", aborting calibration data import.");
|
||||||
@ -1097,7 +1068,7 @@ bool Calibration::SanityCheckSamples(const std::vector<Calibration::Measurement>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Calibration::Point Calibration::getCalibrationPoint(Protocol::Datapoint &d)
|
Calibration::Point Calibration::getCalibrationPoint(VNAData &d)
|
||||||
{
|
{
|
||||||
if(!points.size()) {
|
if(!points.size()) {
|
||||||
throw runtime_error("No calibration points available");
|
throw runtime_error("No calibration points available");
|
||||||
|
@ -45,8 +45,8 @@ public:
|
|||||||
void clearMeasurements();
|
void clearMeasurements();
|
||||||
void clearMeasurements(std::set<Measurement> types);
|
void clearMeasurements(std::set<Measurement> types);
|
||||||
void clearMeasurement(Measurement type);
|
void clearMeasurement(Measurement type);
|
||||||
void addMeasurement(Measurement type, Protocol::Datapoint &d);
|
void addMeasurement(Measurement type, VNAData &d);
|
||||||
void addMeasurements(std::set<Measurement> types, Protocol::Datapoint &d);
|
void addMeasurements(std::set<Measurement> types, VNAData &d);
|
||||||
|
|
||||||
enum class Type {
|
enum class Type {
|
||||||
Port1SOL,
|
Port1SOL,
|
||||||
@ -63,7 +63,7 @@ public:
|
|||||||
bool constructErrorTerms(Type type);
|
bool constructErrorTerms(Type type);
|
||||||
void resetErrorTerms();
|
void resetErrorTerms();
|
||||||
|
|
||||||
void correctMeasurement(Protocol::Datapoint &d);
|
void correctMeasurement(VNAData &d);
|
||||||
void correctTraces(Trace &S11, Trace &S12, Trace &S21, Trace &S22);
|
void correctTraces(Trace &S11, Trace &S12, Trace &S21, Trace &S22);
|
||||||
|
|
||||||
enum class InterpolationType {
|
enum class InterpolationType {
|
||||||
@ -93,7 +93,6 @@ public:
|
|||||||
const std::vector<Measurement> Measurements(Type type = Type::None, bool optional_included = true);
|
const std::vector<Measurement> Measurements(Type type = Type::None, bool optional_included = true);
|
||||||
MeasurementInfo getMeasurementInfo(Measurement m);
|
MeasurementInfo getMeasurementInfo(Measurement m);
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const Calibration& c);
|
|
||||||
friend std::istream& operator >> (std::istream &in, Calibration& c);
|
friend std::istream& operator >> (std::istream &in, Calibration& c);
|
||||||
int nPoints() {
|
int nPoints() {
|
||||||
return points.size();
|
return points.size();
|
||||||
@ -142,7 +141,7 @@ private:
|
|||||||
// Reverse error terms
|
// Reverse error terms
|
||||||
std::complex<double> re33, re11, re23e32, re23e01, re22, re03, rex;
|
std::complex<double> re33, re11, re23e32, re23e01, re22, re03, rex;
|
||||||
};
|
};
|
||||||
Point getCalibrationPoint(Protocol::Datapoint &d);
|
Point getCalibrationPoint(VNAData &d);
|
||||||
/*
|
/*
|
||||||
* Constructs directivity, match and tracking correction factors from measurements of three distinct impedances
|
* Constructs directivity, match and tracking correction factors from measurements of three distinct impedances
|
||||||
* Normally, an open, short and load are used (with ideal reflection coefficients of 1, -1 and 0 respectively).
|
* Normally, an open, short and load are used (with ideal reflection coefficients of 1, -1 and 0 respectively).
|
||||||
@ -174,7 +173,7 @@ private:
|
|||||||
class MeasurementData {
|
class MeasurementData {
|
||||||
public:
|
public:
|
||||||
QDateTime timestamp;
|
QDateTime timestamp;
|
||||||
std::vector<Protocol::Datapoint> datapoints;
|
std::vector<VNAData> datapoints;
|
||||||
};
|
};
|
||||||
Type type;
|
Type type;
|
||||||
|
|
||||||
|
@ -110,12 +110,14 @@ HEADERS += \
|
|||||||
VNA/Deembedding/deembedding.h \
|
VNA/Deembedding/deembedding.h \
|
||||||
VNA/Deembedding/deembeddingdialog.h \
|
VNA/Deembedding/deembeddingdialog.h \
|
||||||
VNA/Deembedding/deembeddingoption.h \
|
VNA/Deembedding/deembeddingoption.h \
|
||||||
|
VNA/Deembedding/impedancerenormalization.h \
|
||||||
VNA/Deembedding/manualdeembeddingdialog.h \
|
VNA/Deembedding/manualdeembeddingdialog.h \
|
||||||
VNA/Deembedding/matchingnetwork.h \
|
VNA/Deembedding/matchingnetwork.h \
|
||||||
VNA/Deembedding/portextension.h \
|
VNA/Deembedding/portextension.h \
|
||||||
VNA/Deembedding/twothru.h \
|
VNA/Deembedding/twothru.h \
|
||||||
VNA/tracewidgetvna.h \
|
VNA/tracewidgetvna.h \
|
||||||
VNA/vna.h \
|
VNA/vna.h \
|
||||||
|
VNA/vnadata.h \
|
||||||
about.h \
|
about.h \
|
||||||
appwindow.h \
|
appwindow.h \
|
||||||
averaging.h \
|
averaging.h \
|
||||||
@ -228,6 +230,7 @@ SOURCES += \
|
|||||||
VNA/Deembedding/deembedding.cpp \
|
VNA/Deembedding/deembedding.cpp \
|
||||||
VNA/Deembedding/deembeddingdialog.cpp \
|
VNA/Deembedding/deembeddingdialog.cpp \
|
||||||
VNA/Deembedding/deembeddingoption.cpp \
|
VNA/Deembedding/deembeddingoption.cpp \
|
||||||
|
VNA/Deembedding/impedancerenormalization.cpp \
|
||||||
VNA/Deembedding/manualdeembeddingdialog.cpp \
|
VNA/Deembedding/manualdeembeddingdialog.cpp \
|
||||||
VNA/Deembedding/matchingnetwork.cpp \
|
VNA/Deembedding/matchingnetwork.cpp \
|
||||||
VNA/Deembedding/portextension.cpp \
|
VNA/Deembedding/portextension.cpp \
|
||||||
@ -293,6 +296,7 @@ FORMS += \
|
|||||||
Traces/waterfallaxisdialog.ui \
|
Traces/waterfallaxisdialog.ui \
|
||||||
Traces/xyplotaxisdialog.ui \
|
Traces/xyplotaxisdialog.ui \
|
||||||
VNA/Deembedding/deembeddingdialog.ui \
|
VNA/Deembedding/deembeddingdialog.ui \
|
||||||
|
VNA/Deembedding/impedancenormalizationdialog.ui \
|
||||||
VNA/Deembedding/manualdeembeddingdialog.ui \
|
VNA/Deembedding/manualdeembeddingdialog.ui \
|
||||||
VNA/Deembedding/matchingnetworkdialog.ui \
|
VNA/Deembedding/matchingnetworkdialog.ui \
|
||||||
VNA/Deembedding/measurementdialog.ui \
|
VNA/Deembedding/measurementdialog.ui \
|
||||||
|
@ -13,7 +13,7 @@ ImpedanceMatchDialog::ImpedanceMatchDialog(MarkerModel &model, Marker *marker, Q
|
|||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
Z0 = Preferences::getInstance().Acquisition.refImp;
|
Z0 = 50.0;
|
||||||
|
|
||||||
// set SI units and prefixes
|
// set SI units and prefixes
|
||||||
ui->zReal->setUnit("Ohm");
|
ui->zReal->setUnit("Ohm");
|
||||||
@ -70,10 +70,13 @@ void ImpedanceMatchDialog::on_cSource_currentIndexChanged(int index)
|
|||||||
auto m = qvariant_cast<Marker*>(ui->cSource->itemData(index));
|
auto m = qvariant_cast<Marker*>(ui->cSource->itemData(index));
|
||||||
ui->rbSeries->setChecked(true);
|
ui->rbSeries->setChecked(true);
|
||||||
auto data = m->getData();
|
auto data = m->getData();
|
||||||
|
Z0 = m->getTrace()->getReferenceImpedance();
|
||||||
auto reflection = Z0 * (1.0 + data) / (1.0 - data);
|
auto reflection = Z0 * (1.0 + data) / (1.0 - data);
|
||||||
ui->zReal->setValue(reflection.real());
|
ui->zReal->setValue(reflection.real());
|
||||||
ui->zImag->setValue(reflection.imag());
|
ui->zImag->setValue(reflection.imag());
|
||||||
ui->zFreq->setValue(m->getPosition());
|
ui->zFreq->setValue(m->getPosition());
|
||||||
|
} else {
|
||||||
|
Z0 = 50.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ QString Marker::readableData(Format f)
|
|||||||
return Unit::ToString(data.real(), "", " ", 5) + "+"+Unit::ToString(data.imag(), "", " ", 5)+"j";
|
return Unit::ToString(data.real(), "", " ", 5) + "+"+Unit::ToString(data.imag(), "", " ", 5)+"j";
|
||||||
case Format::Impedance: {
|
case Format::Impedance: {
|
||||||
auto step = parentTrace->sample(parentTrace->index(position), true).y.real();
|
auto step = parentTrace->sample(parentTrace->index(position), true).y.real();
|
||||||
auto impedance = Util::SparamToImpedance(step).real();
|
auto impedance = Util::SparamToImpedance(step, trace()->getReferenceImpedance()).real();
|
||||||
return Unit::ToString(impedance, "Ω", "m kM", 3);
|
return Unit::ToString(impedance, "Ω", "m kM", 3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -294,8 +294,8 @@ QString Marker::readableData(Format f)
|
|||||||
case Format::Impedance: {
|
case Format::Impedance: {
|
||||||
auto step = parentTrace->sample(parentTrace->index(position), true).y.real();
|
auto step = parentTrace->sample(parentTrace->index(position), true).y.real();
|
||||||
auto stepDelta = delta->parentTrace->sample(delta->parentTrace->index(delta->position), true).y.real();
|
auto stepDelta = delta->parentTrace->sample(delta->parentTrace->index(delta->position), true).y.real();
|
||||||
auto impedance = Util::SparamToImpedance(step).real();
|
auto impedance = Util::SparamToImpedance(step, trace()->getReferenceImpedance()).real();
|
||||||
auto impedanceDelta = Util::SparamToImpedance(stepDelta).real();
|
auto impedanceDelta = Util::SparamToImpedance(stepDelta, trace()->getReferenceImpedance()).real();
|
||||||
return "Δ:"+Unit::ToString(impedance - impedanceDelta, "Ω", "m kM", 3);
|
return "Δ:"+Unit::ToString(impedance - impedanceDelta, "Ω", "m kM", 3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -330,13 +330,13 @@ QString Marker::readableData(Format f)
|
|||||||
}
|
}
|
||||||
case Format::RealImag: return "Δ:"+Unit::ToString(data.real() - delta->data.real(), "", " ", 5) + "+"+Unit::ToString(data.imag() - delta->data.imag(), "", " ", 5)+"j";
|
case Format::RealImag: return "Δ:"+Unit::ToString(data.real() - delta->data.real(), "", " ", 5) + "+"+Unit::ToString(data.imag() - delta->data.imag(), "", " ", 5)+"j";
|
||||||
case Format::Impedance: {
|
case Format::Impedance: {
|
||||||
auto impedance = Util::SparamToImpedance(data);
|
auto impedance = Util::SparamToImpedance(data, trace()->getReferenceImpedance());
|
||||||
auto delta_impedance = Util::SparamToImpedance(delta->data);
|
auto delta_impedance = Util::SparamToImpedance(delta->data, trace()->getReferenceImpedance());
|
||||||
return "Δ:"+Unit::ToString(impedance.real() - delta_impedance.real(), "Ω", "m k", 5) + "+"+Unit::ToString(impedance.imag() - delta_impedance.imag(), "Ω", "m k", 5)+"j";
|
return "Δ:"+Unit::ToString(impedance.real() - delta_impedance.real(), "Ω", "m k", 5) + "+"+Unit::ToString(impedance.imag() - delta_impedance.imag(), "Ω", "m k", 5)+"j";
|
||||||
}
|
}
|
||||||
case Format::SeriesR: return "Δ:"+Unit::ToString(Util::SparamToResistance(data) - Util::SparamToResistance(delta->data), "Ω", "m kM", 4);
|
case Format::SeriesR: return "Δ:"+Unit::ToString(Util::SparamToResistance(data, trace()->getReferenceImpedance()) - Util::SparamToResistance(delta->data, trace()->getReferenceImpedance()), "Ω", "m kM", 4);
|
||||||
case Format::Capacitance: return "Δ:"+Unit::ToString(Util::SparamToCapacitance(data, position) - Util::SparamToCapacitance(delta->data, delta->position), "F", "pnum ", 4);
|
case Format::Capacitance: return "Δ:"+Unit::ToString(Util::SparamToCapacitance(data, position, trace()->getReferenceImpedance()) - Util::SparamToCapacitance(delta->data, delta->position, trace()->getReferenceImpedance()), "F", "pnum ", 4);
|
||||||
case Format::Inductance: return "Δ:"+Unit::ToString(Util::SparamToInductance(data, position) - Util::SparamToInductance(delta->data, delta->position), "H", "pnum ", 4);
|
case Format::Inductance: return "Δ:"+Unit::ToString(Util::SparamToInductance(data, position, trace()->getReferenceImpedance()) - Util::SparamToInductance(delta->data, delta->position, trace()->getReferenceImpedance()), "H", "pnum ", 4);
|
||||||
case Format::QualityFactor: return "ΔQ:" + Unit::ToString(Util::SparamToQualityFactor(data) - Util::SparamToQualityFactor(delta->data), "", " ", 3);
|
case Format::QualityFactor: return "ΔQ:" + Unit::ToString(Util::SparamToQualityFactor(data) - Util::SparamToQualityFactor(delta->data), "", " ", 3);
|
||||||
case Format::Noise: return "Δ:"+Unit::ToString(parentTrace->getNoise(position) - delta->parentTrace->getNoise(delta->position), "dbm/Hz", " ", 3);
|
case Format::Noise: return "Δ:"+Unit::ToString(parentTrace->getNoise(position) - delta->parentTrace->getNoise(delta->position), "dbm/Hz", " ", 3);
|
||||||
default: return "Invalid";
|
default: return "Invalid";
|
||||||
@ -355,9 +355,9 @@ QString Marker::readableData(Format f)
|
|||||||
return "VSWR: NaN";
|
return "VSWR: NaN";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Format::SeriesR: return Unit::ToString(Util::SparamToResistance(data), "Ω", "m kM", 4);
|
case Format::SeriesR: return Unit::ToString(Util::SparamToResistance(data, trace()->getReferenceImpedance()), "Ω", "m kM", 4);
|
||||||
case Format::Capacitance: return Unit::ToString(Util::SparamToCapacitance(data, position), "F", "pnum ", 4);
|
case Format::Capacitance: return Unit::ToString(Util::SparamToCapacitance(data, position, trace()->getReferenceImpedance()), "F", "pnum ", 4);
|
||||||
case Format::Inductance: return Unit::ToString(Util::SparamToInductance(data, position), "H", "pnum ", 4);
|
case Format::Inductance: return Unit::ToString(Util::SparamToInductance(data, position, trace()->getReferenceImpedance()), "H", "pnum ", 4);
|
||||||
case Format::QualityFactor: return "Q:" + Unit::ToString(Util::SparamToQualityFactor(data), "", " ", 3);
|
case Format::QualityFactor: return "Q:" + Unit::ToString(Util::SparamToQualityFactor(data), "", " ", 3);
|
||||||
case Format::Noise: return Unit::ToString(parentTrace->getNoise(position), "dbm/Hz", " ", 3);
|
case Format::Noise: return Unit::ToString(parentTrace->getNoise(position), "dbm/Hz", " ", 3);
|
||||||
case Format::TOI: {
|
case Format::TOI: {
|
||||||
@ -396,7 +396,7 @@ QString Marker::readableData(Format f)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Format::Impedance: {
|
case Format::Impedance: {
|
||||||
auto impedance = Util::SparamToImpedance(data);
|
auto impedance = Util::SparamToImpedance(data, trace()->getReferenceImpedance());
|
||||||
return Unit::ToString(impedance.real(), "Ω", "m k", 5) + "+"+Unit::ToString(impedance.imag(), "Ω", "m k", 5)+"j";
|
return Unit::ToString(impedance.real(), "Ω", "m k", 5) + "+"+Unit::ToString(impedance.imag(), "Ω", "m k", 5)+"j";
|
||||||
}
|
}
|
||||||
case Format::CenterBandwidth:
|
case Format::CenterBandwidth:
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>856</width>
|
<width>881</width>
|
||||||
<height>259</height>
|
<height>334</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -16,11 +16,11 @@
|
|||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,0">
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,1">
|
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,1">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@ -72,6 +72,25 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
|
<property name="title">
|
||||||
|
<string>Reference Impedance</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_3">
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="SIUnitEdit" name="impedance"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Impedance:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -19,6 +19,7 @@ Trace::Trace(QString name, QColor color, LiveParameter live)
|
|||||||
_liveParam(live),
|
_liveParam(live),
|
||||||
vFactor(0.66),
|
vFactor(0.66),
|
||||||
reflection(true),
|
reflection(true),
|
||||||
|
reference_impedance(50.0),
|
||||||
visible(true),
|
visible(true),
|
||||||
paused(false),
|
paused(false),
|
||||||
createdFromFile(false),
|
createdFromFile(false),
|
||||||
@ -61,7 +62,7 @@ void Trace::clear() {
|
|||||||
emit outputSamplesChanged(0, 0);
|
emit outputSamplesChanged(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Trace::addData(const Trace::Data& d, DataType domain) {
|
void Trace::addData(const Trace::Data& d, DataType domain, double reference_impedance) {
|
||||||
if(this->domain != domain) {
|
if(this->domain != domain) {
|
||||||
clear();
|
clear();
|
||||||
this->domain = domain;
|
this->domain = domain;
|
||||||
@ -100,6 +101,10 @@ void Trace::addData(const Trace::Data& d, DataType domain) {
|
|||||||
// insert at this position
|
// insert at this position
|
||||||
data.insert(lower, d);
|
data.insert(lower, d);
|
||||||
}
|
}
|
||||||
|
if(this->reference_impedance != reference_impedance) {
|
||||||
|
this->reference_impedance = reference_impedance;
|
||||||
|
emit typeChanged(this);
|
||||||
|
}
|
||||||
success();
|
success();
|
||||||
emit outputSamplesChanged(index, index + 1);
|
emit outputSamplesChanged(index, index + 1);
|
||||||
}
|
}
|
||||||
@ -154,6 +159,7 @@ void Trace::fillFromTouchstone(Touchstone &t, unsigned int parameter)
|
|||||||
reflection = false;
|
reflection = false;
|
||||||
}
|
}
|
||||||
createdFromFile = true;
|
createdFromFile = true;
|
||||||
|
reference_impedance = t.getReferenceImpedance();
|
||||||
emit typeChanged(this);
|
emit typeChanged(this);
|
||||||
emit outputSamplesChanged(0, data.size());
|
emit outputSamplesChanged(0, data.size());
|
||||||
}
|
}
|
||||||
@ -233,7 +239,7 @@ QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
|
|||||||
return traceName;
|
return traceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Trace::fillFromDatapoints(Trace &S11, Trace &S12, Trace &S21, Trace &S22, const std::vector<Protocol::Datapoint> &data)
|
void Trace::fillFromDatapoints(Trace &S11, Trace &S12, Trace &S21, Trace &S22, const std::vector<VNAData> &data)
|
||||||
{
|
{
|
||||||
S11.clear();
|
S11.clear();
|
||||||
S12.clear();
|
S12.clear();
|
||||||
@ -242,13 +248,13 @@ void Trace::fillFromDatapoints(Trace &S11, Trace &S12, Trace &S21, Trace &S22, c
|
|||||||
for(auto d : data) {
|
for(auto d : data) {
|
||||||
Trace::Data td;
|
Trace::Data td;
|
||||||
td.x = d.frequency;
|
td.x = d.frequency;
|
||||||
td.y = complex<double>(d.real_S11, d.imag_S11);
|
td.y = d.S.m11;
|
||||||
S11.addData(td, DataType::Frequency);
|
S11.addData(td, DataType::Frequency);
|
||||||
td.y = complex<double>(d.real_S12, d.imag_S12);
|
td.y = d.S.m12;
|
||||||
S12.addData(td, DataType::Frequency);
|
S12.addData(td, DataType::Frequency);
|
||||||
td.y = complex<double>(d.real_S21, d.imag_S21);
|
td.y = d.S.m21;
|
||||||
S21.addData(td, DataType::Frequency);
|
S21.addData(td, DataType::Frequency);
|
||||||
td.y = complex<double>(d.real_S22, d.imag_S22);
|
td.y = d.S.m22;
|
||||||
S22.addData(td, DataType::Frequency);
|
S22.addData(td, DataType::Frequency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -287,6 +293,11 @@ void Trace::removeMarker(Marker *m)
|
|||||||
emit markerRemoved(m);
|
emit markerRemoved(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Trace::getReferenceImpedance() const
|
||||||
|
{
|
||||||
|
return reference_impedance;
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<Trace::MathInfo>& Trace::getMathOperations() const
|
const std::vector<Trace::MathInfo>& Trace::getMathOperations() const
|
||||||
{
|
{
|
||||||
return mathOps;
|
return mathOps;
|
||||||
@ -474,12 +485,13 @@ std::vector<Trace *> Trace::createFromCSV(CSV &csv)
|
|||||||
return traces;
|
return traces;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Protocol::Datapoint> Trace::assembleDatapoints(const Trace &S11, const Trace &S12, const Trace &S21, const Trace &S22)
|
std::vector<VNAData> Trace::assembleDatapoints(const Trace &S11, const Trace &S12, const Trace &S21, const Trace &S22)
|
||||||
{
|
{
|
||||||
vector<Protocol::Datapoint> ret;
|
vector<VNAData> ret;
|
||||||
|
|
||||||
// Sanity check traces
|
// Sanity check traces
|
||||||
unsigned int samples = S11.size();
|
unsigned int samples = S11.size();
|
||||||
|
auto impedance = S11.getReferenceImpedance();
|
||||||
vector<const Trace*> traces;
|
vector<const Trace*> traces;
|
||||||
traces.push_back(&S11);
|
traces.push_back(&S11);
|
||||||
traces.push_back(&S12);
|
traces.push_back(&S12);
|
||||||
@ -491,6 +503,10 @@ std::vector<Protocol::Datapoint> Trace::assembleDatapoints(const Trace &S11, con
|
|||||||
qWarning() << "Selected traces do not have the same size";
|
qWarning() << "Selected traces do not have the same size";
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if(t->getReferenceImpedance() != impedance) {
|
||||||
|
qWarning() << "Selected traces do not have the same reference impedance";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
if(t->outputType() != Trace::DataType::Frequency) {
|
if(t->outputType() != Trace::DataType::Frequency) {
|
||||||
qWarning() << "Selected trace not in frequency domain";
|
qWarning() << "Selected trace not in frequency domain";
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
#include "csv.h"
|
#include "csv.h"
|
||||||
#include "Device/device.h"
|
#include "Device/device.h"
|
||||||
#include "Math/tracemath.h"
|
#include "Math/tracemath.h"
|
||||||
|
#include "Tools/parameters.h"
|
||||||
|
#include "tracemodel.h"
|
||||||
|
#include "VNA/vnadata.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <complex>
|
#include <complex>
|
||||||
@ -41,15 +44,14 @@ public:
|
|||||||
Invalid,
|
Invalid,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
void addData(const Data& d, DataType domain);
|
void addData(const Data& d, DataType domain, double reference_impedance = 50.0);
|
||||||
void addData(const Data& d, const Protocol::SpectrumAnalyzerSettings& s);
|
void addData(const Data& d, const Protocol::SpectrumAnalyzerSettings& s);
|
||||||
void setName(QString name);
|
void setName(QString name);
|
||||||
void setVelocityFactor(double v);
|
void setVelocityFactor(double v);
|
||||||
void fillFromTouchstone(Touchstone &t, unsigned int parameter);
|
void fillFromTouchstone(Touchstone &t, unsigned int parameter);
|
||||||
QString fillFromCSV(CSV &csv, unsigned int parameter); // returns the suggested trace name (not yet set in member data)
|
QString fillFromCSV(CSV &csv, unsigned int parameter); // returns the suggested trace name (not yet set in member data)
|
||||||
static void fillFromDatapoints(Trace &S11, Trace &S12, Trace &S21, Trace &S22, const std::vector<Protocol::Datapoint> &data);
|
static void fillFromDatapoints(Trace &S11, Trace &S12, Trace &S21, Trace &S22, const std::vector<VNAData> &data);
|
||||||
void fromLivedata(LivedataType type, LiveParameter param);
|
void fromLivedata(LivedataType type, LiveParameter param);
|
||||||
QString name() { return _name; };
|
QString name() { return _name; };
|
||||||
QColor color() { return _color; };
|
QColor color() { return _color; };
|
||||||
@ -134,7 +136,7 @@ public:
|
|||||||
|
|
||||||
// Assembles datapoints as received from the VNA from four S parameter traces. Requires that all traces are in the frequency domain,
|
// Assembles datapoints as received from the VNA from four S parameter traces. Requires that all traces are in the frequency domain,
|
||||||
// have the same number of samples and their samples must be at the same frequencies across all traces
|
// have the same number of samples and their samples must be at the same frequencies across all traces
|
||||||
static std::vector<Protocol::Datapoint> assembleDatapoints(const Trace &S11, const Trace &S12, const Trace &S21, const Trace &S22);
|
static std::vector<VNAData> assembleDatapoints(const Trace &S11, const Trace &S12, const Trace &S21, const Trace &S22);
|
||||||
|
|
||||||
static LiveParameter ParameterFromString(QString s);
|
static LiveParameter ParameterFromString(QString s);
|
||||||
static QString ParameterToString(LiveParameter p);
|
static QString ParameterToString(LiveParameter p);
|
||||||
@ -144,6 +146,8 @@ public:
|
|||||||
static LivedataType TypeFromString(QString s);
|
static LivedataType TypeFromString(QString s);
|
||||||
static QString TypeToString(LivedataType t);
|
static QString TypeToString(LivedataType t);
|
||||||
|
|
||||||
|
double getReferenceImpedance() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setVisible(bool visible);
|
void setVisible(bool visible);
|
||||||
void setColor(QColor color);
|
void setColor(QColor color);
|
||||||
@ -174,6 +178,7 @@ private:
|
|||||||
bool paused;
|
bool paused;
|
||||||
bool createdFromFile;
|
bool createdFromFile;
|
||||||
bool calibration;
|
bool calibration;
|
||||||
|
double reference_impedance;
|
||||||
DataType domain;
|
DataType domain;
|
||||||
QString filename;
|
QString filename;
|
||||||
unsigned int fileParameter;
|
unsigned int fileParameter;
|
||||||
|
@ -109,11 +109,11 @@ double YAxis::sampleToCoordinate(Trace::Data data, Trace *t, unsigned int sample
|
|||||||
case YAxis::Type::Imaginary:
|
case YAxis::Type::Imaginary:
|
||||||
return data.y.imag();
|
return data.y.imag();
|
||||||
case YAxis::Type::SeriesR:
|
case YAxis::Type::SeriesR:
|
||||||
return Util::SparamToResistance(data.y);
|
return Util::SparamToResistance(data.y, t->getReferenceImpedance());
|
||||||
case YAxis::Type::Reactance:
|
case YAxis::Type::Reactance:
|
||||||
return Util::SparamToImpedance(data.y).imag();
|
return Util::SparamToImpedance(data.y, t->getReferenceImpedance()).imag();
|
||||||
case YAxis::Type::Capacitance:
|
case YAxis::Type::Capacitance:
|
||||||
return Util::SparamToCapacitance(data.y, data.x);
|
return Util::SparamToCapacitance(data.y, data.x, t->getReferenceImpedance());
|
||||||
case YAxis::Type::Inductance:
|
case YAxis::Type::Inductance:
|
||||||
return Util::SparamToInductance(data.y, data.x);
|
return Util::SparamToInductance(data.y, data.x);
|
||||||
case YAxis::Type::QualityFactor:
|
case YAxis::Type::QualityFactor:
|
||||||
@ -164,7 +164,7 @@ double YAxis::sampleToCoordinate(Trace::Data data, Trace *t, unsigned int sample
|
|||||||
}
|
}
|
||||||
double step = t->sample(sample, true).y.real();
|
double step = t->sample(sample, true).y.real();
|
||||||
if(abs(step) < 1.0) {
|
if(abs(step) < 1.0) {
|
||||||
return Util::SparamToImpedance(step).real();
|
return Util::SparamToImpedance(step, t->getReferenceImpedance()).real();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -22,6 +22,9 @@ TraceEditDialog::TraceEditDialog(Trace &t, QWidget *parent) :
|
|||||||
ui->name->setText(t.name());
|
ui->name->setText(t.name());
|
||||||
ui->color->setColor(trace.color());
|
ui->color->setColor(trace.color());
|
||||||
ui->vFactor->setValue(t.velocityFactor());
|
ui->vFactor->setValue(t.velocityFactor());
|
||||||
|
ui->impedance->setUnit("Ω");
|
||||||
|
ui->impedance->setPrecision(3);
|
||||||
|
ui->impedance->setValue(t.getReferenceImpedance());
|
||||||
|
|
||||||
connect(ui->bLive, &QPushButton::clicked, [=](bool live) {
|
connect(ui->bLive, &QPushButton::clicked, [=](bool live) {
|
||||||
if(live) {
|
if(live) {
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1038</width>
|
<width>931</width>
|
||||||
<height>365</height>
|
<height>392</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -21,7 +21,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="0,1">
|
<layout class="QHBoxLayout" name="horizontalLayout_6" stretch="0,1">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
@ -112,6 +112,24 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reference impedance:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="SIUnitEdit" name="impedance">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QStackedWidget" name="stack">
|
<widget class="QStackedWidget" name="stack">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
|
@ -207,7 +207,7 @@ void TraceModel::clearLiveData()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceModel::addVNAData(const Protocol::Datapoint &d, TraceMath::DataType datatype)
|
void TraceModel::addVNAData(const VNAData& d, TraceMath::DataType datatype)
|
||||||
{
|
{
|
||||||
source = DataSource::VNA;
|
source = DataSource::VNA;
|
||||||
for(auto t : traces) {
|
for(auto t : traces) {
|
||||||
@ -225,15 +225,15 @@ void TraceModel::addVNAData(const Protocol::Datapoint &d, TraceMath::DataType da
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch(t->liveParameter()) {
|
switch(t->liveParameter()) {
|
||||||
case Trace::LiveParameter::S11: td.y = complex<double>(d.real_S11, d.imag_S11); break;
|
case Trace::LiveParameter::S11: td.y = d.S.m11; break;
|
||||||
case Trace::LiveParameter::S12: td.y = complex<double>(d.real_S12, d.imag_S12); break;
|
case Trace::LiveParameter::S12: td.y = d.S.m12; break;
|
||||||
case Trace::LiveParameter::S21: td.y = complex<double>(d.real_S21, d.imag_S21); break;
|
case Trace::LiveParameter::S21: td.y = d.S.m21; break;
|
||||||
case Trace::LiveParameter::S22: td.y = complex<double>(d.real_S22, d.imag_S22); break;
|
case Trace::LiveParameter::S22: td.y = d.S.m22; break;
|
||||||
default:
|
default:
|
||||||
// not a VNA trace, skip
|
// not a VNA trace, skip
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
t->addData(td, datatype);
|
t->addData(td, datatype, d.reference_impedance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "Device/device.h"
|
#include "Device/device.h"
|
||||||
#include "savable.h"
|
#include "savable.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
#include "VNA/vnadata.h"
|
||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -64,7 +65,7 @@ signals:
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void clearLiveData();
|
void clearLiveData();
|
||||||
void addVNAData(const Protocol::Datapoint& d, TraceMath::DataType datatype);
|
void addVNAData(const VNAData& d, TraceMath::DataType datatype);
|
||||||
void addSAData(const Protocol::SpectrumAnalyzerResult& d, const Protocol::SpectrumAnalyzerSettings& settings);
|
void addSAData(const Protocol::SpectrumAnalyzerResult& d, const Protocol::SpectrumAnalyzerSettings& settings);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -460,6 +460,12 @@ void TracePlot::checkIfStillSupported(Trace *t)
|
|||||||
if(!configureForTrace(t)) {
|
if(!configureForTrace(t)) {
|
||||||
enableTrace(t, false);
|
enableTrace(t, false);
|
||||||
}
|
}
|
||||||
|
// remove non-supported traces after graph has been adjusted
|
||||||
|
for(auto t : activeTraces()) {
|
||||||
|
if(!supported(t)) {
|
||||||
|
enableTrace(t, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "QFileDialog"
|
#include "QFileDialog"
|
||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
#include "appwindow.h"
|
#include "appwindow.h"
|
||||||
|
#include "CustomWidgets/informationbox.h"
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <array>
|
#include <array>
|
||||||
@ -22,6 +23,7 @@ TraceSmithChart::TraceSmithChart(TraceModel &model, QWidget *parent)
|
|||||||
limitToSpan = true;
|
limitToSpan = true;
|
||||||
limitToEdge = true;
|
limitToEdge = true;
|
||||||
edgeReflection = 1.0;
|
edgeReflection = 1.0;
|
||||||
|
Z0 = 50.0;
|
||||||
initializeTraceInfo();
|
initializeTraceInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +33,7 @@ nlohmann::json TraceSmithChart::toJSON()
|
|||||||
j["limit_to_span"] = limitToSpan;
|
j["limit_to_span"] = limitToSpan;
|
||||||
j["limit_to_edge"] = limitToEdge;
|
j["limit_to_edge"] = limitToEdge;
|
||||||
j["edge_reflection"] = edgeReflection;
|
j["edge_reflection"] = edgeReflection;
|
||||||
|
j["Z0"] = Z0;
|
||||||
nlohmann::json jtraces;
|
nlohmann::json jtraces;
|
||||||
for(auto t : traces) {
|
for(auto t : traces) {
|
||||||
if(t.second) {
|
if(t.second) {
|
||||||
@ -51,6 +54,7 @@ void TraceSmithChart::fromJSON(nlohmann::json j)
|
|||||||
limitToSpan = j.value("limit_to_span", true);
|
limitToSpan = j.value("limit_to_span", true);
|
||||||
limitToEdge = j.value("limit_to_edge", false);
|
limitToEdge = j.value("limit_to_edge", false);
|
||||||
edgeReflection = j.value("edge_reflection", 1.0);
|
edgeReflection = j.value("edge_reflection", 1.0);
|
||||||
|
Z0 = j.value("Z0", 50.0);
|
||||||
for(unsigned int hash : j["traces"]) {
|
for(unsigned int hash : j["traces"]) {
|
||||||
// attempt to find the traces with this hash
|
// attempt to find the traces with this hash
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -107,6 +111,10 @@ void TraceSmithChart::axisSetupDialog()
|
|||||||
ui->zoomReflection->setValue(edgeReflection);
|
ui->zoomReflection->setValue(edgeReflection);
|
||||||
ui->zoomFactor->setValue(1.0/edgeReflection);
|
ui->zoomFactor->setValue(1.0/edgeReflection);
|
||||||
|
|
||||||
|
ui->impedance->setUnit("Ω");
|
||||||
|
ui->impedance->setPrecision(3);
|
||||||
|
ui->impedance->setValue(Z0);
|
||||||
|
|
||||||
auto model = new SmithChartContantLineModel(*this);
|
auto model = new SmithChartContantLineModel(*this);
|
||||||
ui->lineTable->setModel(model);
|
ui->lineTable->setModel(model);
|
||||||
ui->lineTable->setItemDelegateForColumn(SmithChartContantLineModel::ColIndexType, new SmithChartTypeDelegate);
|
ui->lineTable->setItemDelegateForColumn(SmithChartContantLineModel::ColIndexType, new SmithChartTypeDelegate);
|
||||||
@ -125,6 +133,15 @@ void TraceSmithChart::axisSetupDialog()
|
|||||||
edgeReflection = ui->zoomReflection->value();
|
edgeReflection = ui->zoomReflection->value();
|
||||||
ui->zoomFactor->setValueQuiet(1.0 / edgeReflection);
|
ui->zoomFactor->setValueQuiet(1.0 / edgeReflection);
|
||||||
});
|
});
|
||||||
|
connect(ui->impedance, &SIUnitEdit::valueChanged, [=](){
|
||||||
|
Z0 = ui->impedance->value();
|
||||||
|
for(auto t : traces) {
|
||||||
|
if(t.second) {
|
||||||
|
checkIfStillSupported(t.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui->impedance->setValueQuiet(Z0);
|
||||||
|
});
|
||||||
connect(ui->lineTable, &QTableView::clicked, [=](const QModelIndex &index){
|
connect(ui->lineTable, &QTableView::clicked, [=](const QModelIndex &index){
|
||||||
if(index.column() == SmithChartContantLineModel::ColIndexColor) {
|
if(index.column() == SmithChartContantLineModel::ColIndexColor) {
|
||||||
auto line = &constantLines[index.row()];
|
auto line = &constantLines[index.row()];
|
||||||
@ -182,8 +199,7 @@ QPoint TraceSmithChart::dataToPixel(Trace::Data d)
|
|||||||
if(d.x < sweep_fmin || d.x > sweep_fmax) {
|
if(d.x < sweep_fmin || d.x > sweep_fmax) {
|
||||||
return QPoint();
|
return QPoint();
|
||||||
}
|
}
|
||||||
return dataToPixel(d.y);
|
return dataToPixel(d.y);}
|
||||||
}
|
|
||||||
|
|
||||||
std::complex<double> TraceSmithChart::pixelToData(QPoint p)
|
std::complex<double> TraceSmithChart::pixelToData(QPoint p)
|
||||||
{
|
{
|
||||||
@ -265,6 +281,20 @@ bool TraceSmithChart::markerVisible(double x)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TraceSmithChart::configureForTrace(Trace *t)
|
||||||
|
{
|
||||||
|
if(dropSupported(t)) {
|
||||||
|
Z0 = t->getReferenceImpedance();
|
||||||
|
for(auto t : traces) {
|
||||||
|
if(t.second && t.first->getReferenceImpedance() != Z0) {
|
||||||
|
enableTrace(t.first, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void TraceSmithChart::draw(QPainter &p) {
|
void TraceSmithChart::draw(QPainter &p) {
|
||||||
auto pref = Preferences::getInstance();
|
auto pref = Preferences::getInstance();
|
||||||
|
|
||||||
@ -306,7 +336,7 @@ void TraceSmithChart::draw(QPainter &p) {
|
|||||||
p.drawLine(dataToPixel(complex<double>(edgeReflection,0)),dataToPixel(complex<double>(-edgeReflection,0)));
|
p.drawLine(dataToPixel(complex<double>(edgeReflection,0)),dataToPixel(complex<double>(-edgeReflection,0)));
|
||||||
constexpr std::array<double, 5> impedanceLines = {10, 25, 50, 100, 250};
|
constexpr std::array<double, 5> impedanceLines = {10, 25, 50, 100, 250};
|
||||||
for(auto z : impedanceLines) {
|
for(auto z : impedanceLines) {
|
||||||
z /= Preferences::getInstance().Acquisition.refImp;
|
z /= Z0;
|
||||||
auto radius = 1.0/z;
|
auto radius = 1.0/z;
|
||||||
drawArc(SmithChartArc(QPointF(1.0, radius), radius, 0, 2*M_PI));
|
drawArc(SmithChartArc(QPointF(1.0, radius), radius, 0, 2*M_PI));
|
||||||
drawArc(SmithChartArc(QPointF(1.0, -radius), radius, 0, 2*M_PI));
|
drawArc(SmithChartArc(QPointF(1.0, -radius), radius, 0, 2*M_PI));
|
||||||
@ -317,7 +347,7 @@ void TraceSmithChart::draw(QPainter &p) {
|
|||||||
pen = QPen(line.getColor(), pref.Graphs.lineWidth);
|
pen = QPen(line.getColor(), pref.Graphs.lineWidth);
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(true);
|
||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
for(auto arc : line.getArcs()) {
|
for(auto arc : line.getArcs(Z0)) {
|
||||||
drawArc(arc);
|
drawArc(arc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,11 +427,40 @@ void TraceSmithChart::draw(QPainter &p) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TraceSmithChart::traceDropped(Trace *t, QPoint position)
|
||||||
|
{
|
||||||
|
if(!supported(t) && dropSupported(t)) {
|
||||||
|
// needs to switch to a different domain for the graph
|
||||||
|
if(!InformationBox::AskQuestion("Reference impedance change", "You dropped a trace that is not supported with the currently selected reference impedance."
|
||||||
|
" Do you want to remove all traces and change the graph to the correct reference imppedance?", true, "ReferenceImpedanceChangeRequest")) {
|
||||||
|
// user declined to change domain, to not add change impedance
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// attempt to configure for this trace
|
||||||
|
configureForTrace(t);
|
||||||
|
}
|
||||||
|
TracePlot::traceDropped(t, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TraceSmithChart::dropSupported(Trace *t)
|
||||||
|
{
|
||||||
|
if(!t->isReflection()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch(t->outputType()) {
|
||||||
|
case Trace::DataType::Frequency:
|
||||||
|
case Trace::DataType::Power:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString TraceSmithChart::mouseText(QPoint pos)
|
QString TraceSmithChart::mouseText(QPoint pos)
|
||||||
{
|
{
|
||||||
auto data = pixelToData(pos);
|
auto data = pixelToData(pos);
|
||||||
if(abs(data) <= edgeReflection) {
|
if(abs(data) <= edgeReflection) {
|
||||||
data = Preferences::getInstance().Acquisition.refImp * (1.0 + data) / (1.0 - data);
|
data = Z0 * (1.0 + data) / (1.0 - data);
|
||||||
auto ret = Unit::ToString(data.real(), "", " ", 3);
|
auto ret = Unit::ToString(data.real(), "", " ", 3);
|
||||||
if(data.imag() >= 0) {
|
if(data.imag() >= 0) {
|
||||||
ret += "+";
|
ret += "+";
|
||||||
@ -478,16 +537,10 @@ void TraceSmithChart::updateContextMenu()
|
|||||||
|
|
||||||
bool TraceSmithChart::supported(Trace *t)
|
bool TraceSmithChart::supported(Trace *t)
|
||||||
{
|
{
|
||||||
if(!t->isReflection()) {
|
if(t->getReferenceImpedance() != Z0) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
switch(t->outputType()) {
|
|
||||||
case Trace::DataType::Frequency:
|
|
||||||
case Trace::DataType::Power:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return dropSupported(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
SmithChartArc::SmithChartArc(QPointF center, double radius, double startAngle, double spanAngle)
|
SmithChartArc::SmithChartArc(QPointF center, double radius, double startAngle, double spanAngle)
|
||||||
@ -571,9 +624,8 @@ SmithChartConstantLine::SmithChartConstantLine()
|
|||||||
color = Qt::darkRed;
|
color = Qt::darkRed;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SmithChartArc> SmithChartConstantLine::getArcs()
|
std::vector<SmithChartArc> SmithChartConstantLine::getArcs(double Z0)
|
||||||
{
|
{
|
||||||
double Z0 = Preferences::getInstance().Acquisition.refImp;
|
|
||||||
std::vector<SmithChartArc> arcs;
|
std::vector<SmithChartArc> arcs;
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case Type::VSWR:
|
case Type::VSWR:
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
SmithChartConstantLine();
|
SmithChartConstantLine();
|
||||||
std::vector<SmithChartArc> getArcs();
|
std::vector<SmithChartArc> getArcs(double Z0);
|
||||||
QColor getColor() const;
|
QColor getColor() const;
|
||||||
void setColor(const QColor &value);
|
void setColor(const QColor &value);
|
||||||
|
|
||||||
@ -126,13 +126,17 @@ protected:
|
|||||||
virtual bool markerVisible(double x);
|
virtual bool markerVisible(double x);
|
||||||
|
|
||||||
//void paintEvent(QPaintEvent *event) override;
|
//void paintEvent(QPaintEvent *event) override;
|
||||||
|
virtual bool configureForTrace(Trace *t);
|
||||||
virtual void updateContextMenu() override;
|
virtual void updateContextMenu() override;
|
||||||
bool supported(Trace *t) override;
|
bool supported(Trace *t) override;
|
||||||
virtual void draw(QPainter& painter) override;
|
virtual void draw(QPainter& painter) override;
|
||||||
|
virtual void traceDropped(Trace *t, QPoint position) override;
|
||||||
|
virtual bool dropSupported(Trace *t) override;
|
||||||
QString mouseText(QPoint pos) override;
|
QString mouseText(QPoint pos) override;
|
||||||
bool limitToSpan;
|
bool limitToSpan;
|
||||||
bool limitToEdge;
|
bool limitToEdge;
|
||||||
double edgeReflection; // magnitude of reflection coefficient at the edge of the smith chart (zoom factor)
|
double edgeReflection; // magnitude of reflection coefficient at the edge of the smith chart (zoom factor)
|
||||||
|
double Z0;
|
||||||
QTransform transform;
|
QTransform transform;
|
||||||
std::vector<SmithChartConstantLine> constantLines;
|
std::vector<SmithChartConstantLine> constantLines;
|
||||||
};
|
};
|
||||||
|
@ -68,6 +68,7 @@ void TraceTouchstoneExport::on_buttonBox_accepted()
|
|||||||
if(filename.length() > 0) {
|
if(filename.length() > 0) {
|
||||||
auto ports = ui->sbPorts->value();
|
auto ports = ui->sbPorts->value();
|
||||||
auto t = Touchstone(ports);
|
auto t = Touchstone(ports);
|
||||||
|
t.setReferenceImpedance(referenceImpedance);
|
||||||
// add trace points to touchstone
|
// add trace points to touchstone
|
||||||
for(unsigned int s=0;s<points;s++) {
|
for(unsigned int s=0;s<points;s++) {
|
||||||
Touchstone::Datapoint tData;
|
Touchstone::Datapoint tData;
|
||||||
@ -165,6 +166,7 @@ void TraceTouchstoneExport::selectionChanged(QComboBox *w)
|
|||||||
// the first trace has been selected, extract frequency info
|
// the first trace has been selected, extract frequency info
|
||||||
Trace *t = qvariant_cast<Trace*>(w->itemData(w->currentIndex()));
|
Trace *t = qvariant_cast<Trace*>(w->itemData(w->currentIndex()));
|
||||||
points = t->size();
|
points = t->size();
|
||||||
|
referenceImpedance = t->getReferenceImpedance();
|
||||||
ui->points->setText(QString::number(points));
|
ui->points->setText(QString::number(points));
|
||||||
if(points > 0) {
|
if(points > 0) {
|
||||||
lowerFreq = t->minX();
|
lowerFreq = t->minX();
|
||||||
@ -179,7 +181,7 @@ void TraceTouchstoneExport::selectionChanged(QComboBox *w)
|
|||||||
for(auto c : v1) {
|
for(auto c : v1) {
|
||||||
for(int i=1;i<c->count();i++) {
|
for(int i=1;i<c->count();i++) {
|
||||||
Trace *t = qvariant_cast<Trace*>(c->itemData(i));
|
Trace *t = qvariant_cast<Trace*>(c->itemData(i));
|
||||||
if(t->size() != points || (points > 0 && (t->minX() != lowerFreq || t->maxX() != upperFreq))) {
|
if(t->getReferenceImpedance() != referenceImpedance || t->size() != points || (points > 0 && (t->minX() != lowerFreq || t->maxX() != upperFreq))) {
|
||||||
// this trace is not available anymore
|
// this trace is not available anymore
|
||||||
c->removeItem(i);
|
c->removeItem(i);
|
||||||
// decrement to check the next index in the next loop iteration
|
// decrement to check the next index in the next loop iteration
|
||||||
|
@ -34,6 +34,7 @@ private:
|
|||||||
unsigned int ports;
|
unsigned int ports;
|
||||||
unsigned int points;
|
unsigned int points;
|
||||||
double lowerFreq, upperFreq;
|
double lowerFreq, upperFreq;
|
||||||
|
double referenceImpedance;
|
||||||
bool freqsSet;
|
bool freqsSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,13 +62,13 @@ double Util::distanceToLine(QPointF point, QPointF l1, QPointF l2, QPointF *clos
|
|||||||
return orthVect.length();
|
return orthVect.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::complex<double> Util::SparamToImpedance(std::complex<double> d) {
|
std::complex<double> Util::SparamToImpedance(std::complex<double> d, std::complex<double> Z0) {
|
||||||
return Preferences::getInstance().Acquisition.refImp * (1.0 + d) / (1.0 - d);
|
return Z0 * (1.0 + d) / (1.0 - d);
|
||||||
}
|
}
|
||||||
|
|
||||||
double Util::dBmTodBuV(double dBm)
|
double Util::dBmTodBuV(double dBm)
|
||||||
{
|
{
|
||||||
double uVpower = 0.000001*0.000001/Preferences::getInstance().Acquisition.refImp;
|
double uVpower = 0.000001*0.000001/50.0;
|
||||||
double dBdiff = 10*log10(uVpower*1000);
|
double dBdiff = 10*log10(uVpower*1000);
|
||||||
return dBm - dBdiff;
|
return dBm - dBdiff;
|
||||||
}
|
}
|
||||||
|
@ -45,16 +45,16 @@ namespace Util {
|
|||||||
static inline double SparamToVSWR(std::complex<double> d) {
|
static inline double SparamToVSWR(std::complex<double> d) {
|
||||||
return SparamToVSWR(abs(d));
|
return SparamToVSWR(abs(d));
|
||||||
}
|
}
|
||||||
std::complex<double> SparamToImpedance(std::complex<double> d);
|
std::complex<double> SparamToImpedance(std::complex<double> d, std::complex<double> Z0 = 50.0);
|
||||||
// all these conversions assume series connection of real and imag part
|
// all these conversions assume series connection of real and imag part
|
||||||
static inline double SparamToResistance(std::complex<double> d) {
|
static inline double SparamToResistance(std::complex<double> d, std::complex<double> Z0 = 50.0) {
|
||||||
return SparamToImpedance(d).real();
|
return SparamToImpedance(d, Z0).real();
|
||||||
}
|
}
|
||||||
static inline double SparamToCapacitance(std::complex<double> d, double freq) {
|
static inline double SparamToCapacitance(std::complex<double> d, double freq, std::complex<double> Z0 = 50.0) {
|
||||||
return -1.0 / (SparamToImpedance(d).imag() * 2.0 * M_PI * freq);
|
return -1.0 / (SparamToImpedance(d, Z0).imag() * 2.0 * M_PI * freq);
|
||||||
}
|
}
|
||||||
static inline double SparamToInductance(std::complex<double> d, double freq) {
|
static inline double SparamToInductance(std::complex<double> d, double freq, std::complex<double> Z0 = 50.0) {
|
||||||
return SparamToImpedance(d).imag() / (2.0 * M_PI * freq);
|
return SparamToImpedance(d, Z0).imag() / (2.0 * M_PI * freq);
|
||||||
}
|
}
|
||||||
static inline double SparamToQualityFactor(std::complex<double> d) {
|
static inline double SparamToQualityFactor(std::complex<double> d) {
|
||||||
return abs(d.imag()) / d.real();
|
return abs(d.imag()) / d.real();
|
||||||
|
@ -120,7 +120,7 @@ Deembedding::Deembedding(TraceModel &tm)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Deembedding::Deembed(Protocol::Datapoint &d)
|
void Deembedding::Deembed(VNAData &d)
|
||||||
{
|
{
|
||||||
// figure out the point in one sweep based on the incomig pointNums
|
// figure out the point in one sweep based on the incomig pointNums
|
||||||
static unsigned lastPointNum;
|
static unsigned lastPointNum;
|
||||||
|
@ -19,7 +19,7 @@ public:
|
|||||||
Deembedding(TraceModel &tm);
|
Deembedding(TraceModel &tm);
|
||||||
~Deembedding(){};
|
~Deembedding(){};
|
||||||
|
|
||||||
void Deembed(Protocol::Datapoint &d);
|
void Deembed(VNAData &d);
|
||||||
void Deembed(Trace &S11, Trace &S12, Trace &S21, Trace &S22);
|
void Deembed(Trace &S11, Trace &S12, Trace &S21, Trace &S22);
|
||||||
|
|
||||||
void removeOption(unsigned int index);
|
void removeOption(unsigned int index);
|
||||||
@ -42,7 +42,7 @@ private:
|
|||||||
TraceModel &tm;
|
TraceModel &tm;
|
||||||
|
|
||||||
bool measuring;
|
bool measuring;
|
||||||
std::vector<Protocol::Datapoint> measurements;
|
std::vector<VNAData> measurements;
|
||||||
QDialog *measurementDialog;
|
QDialog *measurementDialog;
|
||||||
Ui_DeembeddingMeasurementDialog *measurementUI;
|
Ui_DeembeddingMeasurementDialog *measurementUI;
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "portextension.h"
|
#include "portextension.h"
|
||||||
#include "twothru.h"
|
#include "twothru.h"
|
||||||
#include "matchingnetwork.h"
|
#include "matchingnetwork.h"
|
||||||
|
#include "impedancerenormalization.h"
|
||||||
|
|
||||||
DeembeddingOption *DeembeddingOption::create(DeembeddingOption::Type type)
|
DeembeddingOption *DeembeddingOption::create(DeembeddingOption::Type type)
|
||||||
{
|
{
|
||||||
@ -13,6 +14,8 @@ DeembeddingOption *DeembeddingOption::create(DeembeddingOption::Type type)
|
|||||||
return new TwoThru();
|
return new TwoThru();
|
||||||
case Type::MatchingNetwork:
|
case Type::MatchingNetwork:
|
||||||
return new MatchingNetwork();
|
return new MatchingNetwork();
|
||||||
|
case Type::ImpedanceRenormalization:
|
||||||
|
return new ImpedanceRenormalization();
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -27,6 +30,8 @@ QString DeembeddingOption::getName(DeembeddingOption::Type type)
|
|||||||
return "2xThru";
|
return "2xThru";
|
||||||
case Type::MatchingNetwork:
|
case Type::MatchingNetwork:
|
||||||
return "Matching Network";
|
return "Matching Network";
|
||||||
|
case Type::ImpedanceRenormalization:
|
||||||
|
return "Impedance Renormalization";
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "savable.h"
|
#include "savable.h"
|
||||||
#include "Device/device.h"
|
#include "Device/device.h"
|
||||||
|
#include "Traces/tracemodel.h"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ public:
|
|||||||
PortExtension,
|
PortExtension,
|
||||||
TwoThru,
|
TwoThru,
|
||||||
MatchingNetwork,
|
MatchingNetwork,
|
||||||
|
ImpedanceRenormalization,
|
||||||
// Add new deembedding options here, do not explicitly assign values and keep the Last entry at the last position
|
// Add new deembedding options here, do not explicitly assign values and keep the Last entry at the last position
|
||||||
Last,
|
Last,
|
||||||
};
|
};
|
||||||
@ -21,12 +23,12 @@ public:
|
|||||||
static DeembeddingOption *create(Type type);
|
static DeembeddingOption *create(Type type);
|
||||||
static QString getName(Type type);
|
static QString getName(Type type);
|
||||||
|
|
||||||
virtual void transformDatapoint(Protocol::Datapoint &p) = 0;
|
virtual void transformDatapoint(VNAData &p) = 0;
|
||||||
virtual void edit(){};
|
virtual void edit(){};
|
||||||
virtual Type getType() = 0;
|
virtual Type getType() = 0;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void measurementCompleted(std::vector<Protocol::Datapoint> m){Q_UNUSED(m)};
|
virtual void measurementCompleted(std::vector<VNAData> m){Q_UNUSED(m)};
|
||||||
signals:
|
signals:
|
||||||
// Deembedding option may selfdestruct if not applicable with current settings. It should emit this signal before deleting itself
|
// Deembedding option may selfdestruct if not applicable with current settings. It should emit this signal before deleting itself
|
||||||
void deleted(DeembeddingOption *option);
|
void deleted(DeembeddingOption *option);
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ImpedanceRenormalizationDialog</class>
|
||||||
|
<widget class="QDialog" name="ImpedanceRenormalizationDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>241</width>
|
||||||
|
<height>76</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>S parameter renormalization</string>
|
||||||
|
</property>
|
||||||
|
<property name="modal">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Normalize to:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="SIUnitEdit" name="impedance"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>SIUnitEdit</class>
|
||||||
|
<extends>QLineEdit</extends>
|
||||||
|
<header>CustomWidgets/siunitedit.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>ImpedanceRenormalizationDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>ImpedanceRenormalizationDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
@ -0,0 +1,57 @@
|
|||||||
|
#include "impedancerenormalization.h"
|
||||||
|
|
||||||
|
#include "ui_impedancenormalizationdialog.h"
|
||||||
|
#include "Tools/parameters.h"
|
||||||
|
#include "appwindow.h"
|
||||||
|
|
||||||
|
#include <complex>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
ImpedanceRenormalization::ImpedanceRenormalization()
|
||||||
|
: DeembeddingOption(),
|
||||||
|
impedance(50.0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImpedanceRenormalization::transformDatapoint(VNAData &p)
|
||||||
|
{
|
||||||
|
p.S = Sparam(ABCDparam(p.S, p.reference_impedance), impedance);
|
||||||
|
p.reference_impedance = impedance;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json ImpedanceRenormalization::toJSON()
|
||||||
|
{
|
||||||
|
nlohmann::json j;
|
||||||
|
j["impedance"] = impedance;
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImpedanceRenormalization::fromJSON(nlohmann::json j)
|
||||||
|
{
|
||||||
|
impedance = j.value("impedance", impedance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImpedanceRenormalization::edit()
|
||||||
|
{
|
||||||
|
auto dialog = new QDialog();
|
||||||
|
ui = new Ui::ImpedanceRenormalizationDialog();
|
||||||
|
ui->setupUi(dialog);
|
||||||
|
connect(dialog, &QDialog::finished, [=](){
|
||||||
|
delete ui;
|
||||||
|
});
|
||||||
|
|
||||||
|
// set initial values
|
||||||
|
ui->impedance->setUnit("Ω");
|
||||||
|
ui->impedance->setPrecision(3);
|
||||||
|
ui->impedance->setValue(impedance);
|
||||||
|
|
||||||
|
connect(ui->impedance, &SIUnitEdit::valueChanged, [&](double newval){
|
||||||
|
impedance = newval;
|
||||||
|
});
|
||||||
|
|
||||||
|
if(AppWindow::showGUI()) {
|
||||||
|
dialog->show();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef IMPEDANCERENORMALIZATION_H
|
||||||
|
#define IMPEDANCERENORMALIZATION_H
|
||||||
|
|
||||||
|
#include "deembeddingoption.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ImpedanceRenormalizationDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ImpedanceRenormalization : public DeembeddingOption
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ImpedanceRenormalization();
|
||||||
|
|
||||||
|
void transformDatapoint(VNAData &p) override;
|
||||||
|
Type getType() override { return Type::ImpedanceRenormalization;}
|
||||||
|
nlohmann::json toJSON() override;
|
||||||
|
void fromJSON(nlohmann::json j) override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void edit() override;
|
||||||
|
private:
|
||||||
|
double impedance;
|
||||||
|
|
||||||
|
Ui::ImpedanceRenormalizationDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMPEDANCERENORMALIZATION_H
|
@ -26,13 +26,10 @@ MatchingNetwork::MatchingNetwork()
|
|||||||
addNetwork = true;
|
addNetwork = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchingNetwork::transformDatapoint(Protocol::Datapoint &p)
|
void MatchingNetwork::transformDatapoint(VNAData &p)
|
||||||
{
|
{
|
||||||
auto S = Sparam(complex<double>(p.real_S11, p.imag_S11),
|
auto S = p.S;
|
||||||
complex<double>(p.real_S12, p.imag_S12),
|
auto measurement = ABCDparam(S, p.reference_impedance);
|
||||||
complex<double>(p.real_S21, p.imag_S21),
|
|
||||||
complex<double>(p.real_S22, p.imag_S22));
|
|
||||||
auto measurement = ABCDparam(S, Preferences::getInstance().Acquisition.refImp);
|
|
||||||
if(matching.count(p.frequency) == 0) {
|
if(matching.count(p.frequency) == 0) {
|
||||||
// this point is not calculated yet
|
// this point is not calculated yet
|
||||||
MatchingPoint m;
|
MatchingPoint m;
|
||||||
@ -56,15 +53,7 @@ void MatchingNetwork::transformDatapoint(Protocol::Datapoint &p)
|
|||||||
// at this point the map contains the matching network effect
|
// at this point the map contains the matching network effect
|
||||||
auto m = matching[p.frequency];
|
auto m = matching[p.frequency];
|
||||||
auto corrected = m.p1 * measurement * m.p2;
|
auto corrected = m.p1 * measurement * m.p2;
|
||||||
S = Sparam(corrected, Preferences::getInstance().Acquisition.refImp);
|
p.S = Sparam(corrected, p.reference_impedance);
|
||||||
p.real_S11 = real(S.m11);
|
|
||||||
p.imag_S11 = imag(S.m11);
|
|
||||||
p.real_S12 = real(S.m12);
|
|
||||||
p.imag_S12 = imag(S.m12);
|
|
||||||
p.real_S21 = real(S.m21);
|
|
||||||
p.imag_S21 = imag(S.m21);
|
|
||||||
p.real_S22 = real(S.m22);
|
|
||||||
p.imag_S22 = imag(S.m22);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchingNetwork::edit()
|
void MatchingNetwork::edit()
|
||||||
@ -541,7 +530,7 @@ ABCDparam MatchingComponent::parameters(double freq)
|
|||||||
} else {
|
} else {
|
||||||
auto d = touchstone->interpolate(freq);
|
auto d = touchstone->interpolate(freq);
|
||||||
auto S = Sparam(d.S[0], d.S[1], d.S[2], d.S[3]);
|
auto S = Sparam(d.S[0], d.S[1], d.S[2], d.S[3]);
|
||||||
return ABCDparam(S, Preferences::getInstance().Acquisition.refImp);
|
return ABCDparam(S, 50.0);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return ABCDparam(1.0, 0.0, 0.0, 1.0);
|
return ABCDparam(1.0, 0.0, 0.0, 1.0);
|
||||||
|
@ -64,9 +64,9 @@ public:
|
|||||||
|
|
||||||
// DeembeddingOption interface
|
// DeembeddingOption interface
|
||||||
public:
|
public:
|
||||||
void transformDatapoint(Protocol::Datapoint &p) override;
|
void transformDatapoint(VNAData &p) override;
|
||||||
void edit() override;
|
void edit() override;
|
||||||
Type getType() override {return Type::MatchingNetwork;};
|
Type getType() override {return Type::MatchingNetwork;}
|
||||||
nlohmann::json toJSON() override;
|
nlohmann::json toJSON() override;
|
||||||
void fromJSON(nlohmann::json j) override;
|
void fromJSON(nlohmann::json j) override;
|
||||||
private:
|
private:
|
||||||
|
@ -29,15 +29,9 @@ PortExtension::PortExtension()
|
|||||||
kit = nullptr;
|
kit = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PortExtension::transformDatapoint(Protocol::Datapoint &d)
|
void PortExtension::transformDatapoint(VNAData &d)
|
||||||
{
|
{
|
||||||
if(port1.enabled || port2.enabled) {
|
if(port1.enabled || port2.enabled) {
|
||||||
// Convert measurements to complex variables
|
|
||||||
auto S11 = complex<double>(d.real_S11, d.imag_S11);
|
|
||||||
auto S21 = complex<double>(d.real_S21, d.imag_S21);
|
|
||||||
auto S22 = complex<double>(d.real_S22, d.imag_S22);
|
|
||||||
auto S12 = complex<double>(d.real_S12, d.imag_S12);
|
|
||||||
|
|
||||||
if(port1.enabled) {
|
if(port1.enabled) {
|
||||||
auto phase = -2 * M_PI * port1.delay * d.frequency;
|
auto phase = -2 * M_PI * port1.delay * d.frequency;
|
||||||
auto db_attennuation = port1.DCloss;
|
auto db_attennuation = port1.DCloss;
|
||||||
@ -47,9 +41,9 @@ void PortExtension::transformDatapoint(Protocol::Datapoint &d)
|
|||||||
// convert from db to factor
|
// convert from db to factor
|
||||||
auto att = pow(10.0, -db_attennuation / 20.0);
|
auto att = pow(10.0, -db_attennuation / 20.0);
|
||||||
auto correction = polar<double>(att, phase);
|
auto correction = polar<double>(att, phase);
|
||||||
S11 /= correction * correction;
|
d.S.m11 /= correction * correction;
|
||||||
S21 /= correction;
|
d.S.m21 /= correction;
|
||||||
S12 /= correction;
|
d.S.m12 /= correction;
|
||||||
}
|
}
|
||||||
if(port2.enabled) {
|
if(port2.enabled) {
|
||||||
auto phase = -2 * M_PI * port2.delay * d.frequency;
|
auto phase = -2 * M_PI * port2.delay * d.frequency;
|
||||||
@ -60,18 +54,10 @@ void PortExtension::transformDatapoint(Protocol::Datapoint &d)
|
|||||||
// convert from db to factor
|
// convert from db to factor
|
||||||
auto att = pow(10.0, -db_attennuation / 20.0);
|
auto att = pow(10.0, -db_attennuation / 20.0);
|
||||||
auto correction = polar<double>(att, phase);
|
auto correction = polar<double>(att, phase);
|
||||||
S22 /= correction * correction;
|
d.S.m22 /= correction * correction;
|
||||||
S21 /= correction;
|
d.S.m21 /= correction;
|
||||||
S12 /= correction;
|
d.S.m12 /= correction;
|
||||||
}
|
}
|
||||||
d.real_S11 = S11.real();
|
|
||||||
d.imag_S11 = S11.imag();
|
|
||||||
d.real_S12 = S12.real();
|
|
||||||
d.imag_S12 = S12.imag();
|
|
||||||
d.real_S21 = S21.real();
|
|
||||||
d.imag_S21 = S21.imag();
|
|
||||||
d.real_S22 = S22.real();
|
|
||||||
d.imag_S22 = S22.imag();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +194,7 @@ void PortExtension::edit()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PortExtension::measurementCompleted(std::vector<Protocol::Datapoint> m)
|
void PortExtension::measurementCompleted(std::vector<VNAData> m)
|
||||||
{
|
{
|
||||||
if(m.size() > 0) {
|
if(m.size() > 0) {
|
||||||
double last_phase = 0.0;
|
double last_phase = 0.0;
|
||||||
@ -219,9 +205,9 @@ void PortExtension::measurementCompleted(std::vector<Protocol::Datapoint> m)
|
|||||||
// grab correct measurement
|
// grab correct measurement
|
||||||
complex<double> reflection;
|
complex<double> reflection;
|
||||||
if(isPort1) {
|
if(isPort1) {
|
||||||
reflection = complex<double>(p.real_S11, p.imag_S11);
|
reflection = p.S.m11;
|
||||||
} else {
|
} else {
|
||||||
reflection = complex<double>(p.real_S22, p.imag_S22);
|
reflection = p.S.m22;
|
||||||
}
|
}
|
||||||
// remove calkit if specified
|
// remove calkit if specified
|
||||||
if(!isIdeal) {
|
if(!isIdeal) {
|
||||||
|
@ -18,14 +18,14 @@ class PortExtension : public DeembeddingOption
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
PortExtension();
|
PortExtension();
|
||||||
void transformDatapoint(Protocol::Datapoint& d) override;
|
void transformDatapoint(VNAData& d) override;
|
||||||
void setCalkit(Calkit *kit);
|
void setCalkit(Calkit *kit);
|
||||||
Type getType() override {return Type::PortExtension;}
|
Type getType() override {return Type::PortExtension;}
|
||||||
nlohmann::json toJSON() override;
|
nlohmann::json toJSON() override;
|
||||||
void fromJSON(nlohmann::json j) override;
|
void fromJSON(nlohmann::json j) override;
|
||||||
public slots:
|
public slots:
|
||||||
void edit() override;
|
void edit() override;
|
||||||
void measurementCompleted(std::vector<Protocol::Datapoint> m) override;
|
void measurementCompleted(std::vector<VNAData> m) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startMeasurement();
|
void startMeasurement();
|
||||||
|
@ -12,19 +12,14 @@ using namespace std;
|
|||||||
|
|
||||||
TwoThru::TwoThru()
|
TwoThru::TwoThru()
|
||||||
{
|
{
|
||||||
Z0 = Preferences::getInstance().Acquisition.refImp;
|
Z0 = 50.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwoThru::transformDatapoint(Protocol::Datapoint &p)
|
void TwoThru::transformDatapoint(VNAData &p)
|
||||||
{
|
{
|
||||||
// correct measurement
|
// correct measurement
|
||||||
if(points.size() > 0) {
|
if(points.size() > 0) {
|
||||||
auto S11 = complex<double>(p.real_S11, p.imag_S11);
|
Tparam meas(p.S);
|
||||||
auto S12 = complex<double>(p.real_S12, p.imag_S12);
|
|
||||||
auto S21 = complex<double>(p.real_S21, p.imag_S21);
|
|
||||||
auto S22 = complex<double>(p.real_S22, p.imag_S22);
|
|
||||||
Sparam S(S11, S12, S21, S22);
|
|
||||||
Tparam meas(S);
|
|
||||||
|
|
||||||
Tparam inv1, inv2;
|
Tparam inv1, inv2;
|
||||||
if(p.frequency < points.front().freq) {
|
if(p.frequency < points.front().freq) {
|
||||||
@ -54,15 +49,7 @@ void TwoThru::transformDatapoint(Protocol::Datapoint &p)
|
|||||||
// perform correction
|
// perform correction
|
||||||
Tparam corrected = inv1*meas*inv2;
|
Tparam corrected = inv1*meas*inv2;
|
||||||
// transform back into S parameters
|
// transform back into S parameters
|
||||||
S = Sparam(corrected);
|
p.S = Sparam(corrected);
|
||||||
p.real_S11 = real(S.m11);
|
|
||||||
p.imag_S11 = imag(S.m11);
|
|
||||||
p.real_S12 = real(S.m12);
|
|
||||||
p.imag_S12 = imag(S.m12);
|
|
||||||
p.real_S21 = real(S.m21);
|
|
||||||
p.imag_S21 = imag(S.m21);
|
|
||||||
p.real_S22 = real(S.m22);
|
|
||||||
p.imag_S22 = imag(S.m22);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +99,7 @@ void TwoThru::updateGUI()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwoThru::measurementCompleted(std::vector<Protocol::Datapoint> m)
|
void TwoThru::measurementCompleted(std::vector<VNAData> m)
|
||||||
{
|
{
|
||||||
if (measuring2xthru) {
|
if (measuring2xthru) {
|
||||||
measurements2xthru = m;
|
measurements2xthru = m;
|
||||||
@ -223,7 +210,7 @@ void TwoThru::fromJSON(nlohmann::json j)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<Protocol::Datapoint> data_2xthru)
|
std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<VNAData> data_2xthru)
|
||||||
{
|
{
|
||||||
// calculate error boxes, see https://www.freelists.org/post/si-list/IEEE-P370-Opensource-Deembedding-MATLAB-functions
|
// calculate error boxes, see https://www.freelists.org/post/si-list/IEEE-P370-Opensource-Deembedding-MATLAB-functions
|
||||||
// create vectors of S parameters
|
// create vectors of S parameters
|
||||||
@ -242,10 +229,10 @@ std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<Protocol::D
|
|||||||
// ignore possible DC point
|
// ignore possible DC point
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
S11.push_back(complex<double>(m.real_S11, m.imag_S11));
|
S11.push_back(m.S.m11);
|
||||||
S12.push_back(complex<double>(m.real_S12, m.imag_S12));
|
S12.push_back(m.S.m12);
|
||||||
S21.push_back(complex<double>(m.real_S21, m.imag_S21));
|
S21.push_back(m.S.m21);
|
||||||
S22.push_back(complex<double>(m.real_S22, m.imag_S22));
|
S22.push_back(m.S.m22);
|
||||||
f.push_back(m.frequency);
|
f.push_back(m.frequency);
|
||||||
}
|
}
|
||||||
auto n = f.size();
|
auto n = f.size();
|
||||||
@ -403,7 +390,7 @@ std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<Protocol::D
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<Protocol::Datapoint> data_2xthru, std::vector<Protocol::Datapoint> data_fix_dut_fix, double z0)
|
std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<VNAData> data_2xthru, std::vector<VNAData> data_fix_dut_fix, double z0)
|
||||||
{
|
{
|
||||||
vector<Point> ret;
|
vector<Point> ret;
|
||||||
|
|
||||||
@ -427,19 +414,13 @@ std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<Protocol::D
|
|||||||
vector<Sparam> p;
|
vector<Sparam> p;
|
||||||
vector<double> f;
|
vector<double> f;
|
||||||
for(auto d : data_2xthru) {
|
for(auto d : data_2xthru) {
|
||||||
p.push_back(Sparam(complex<double>(d.real_S11, d.imag_S11),
|
p.push_back(d.S);
|
||||||
complex<double>(d.real_S12, d.imag_S12),
|
|
||||||
complex<double>(d.real_S21, d.imag_S21),
|
|
||||||
complex<double>(d.real_S22, d.imag_S22)));
|
|
||||||
f.push_back(d.frequency);
|
f.push_back(d.frequency);
|
||||||
}
|
}
|
||||||
auto data_2xthru_Sparam = p;
|
auto data_2xthru_Sparam = p;
|
||||||
vector<Sparam> data_fix_dut_fix_Sparam;
|
vector<Sparam> data_fix_dut_fix_Sparam;
|
||||||
for(auto d : data_fix_dut_fix) {
|
for(auto d : data_fix_dut_fix) {
|
||||||
data_fix_dut_fix_Sparam.push_back(Sparam(complex<double>(d.real_S11, d.imag_S11),
|
data_fix_dut_fix_Sparam.push_back(d.S);
|
||||||
complex<double>(d.real_S12, d.imag_S12),
|
|
||||||
complex<double>(d.real_S21, d.imag_S21),
|
|
||||||
complex<double>(d.real_S22, d.imag_S22)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// grabbing S21
|
// grabbing S21
|
||||||
@ -682,9 +663,9 @@ std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<Protocol::D
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Protocol::Datapoint> TwoThru::interpolateEvenFrequencySteps(std::vector<Protocol::Datapoint> input)
|
std::vector<VNAData> TwoThru::interpolateEvenFrequencySteps(std::vector<VNAData> input)
|
||||||
{
|
{
|
||||||
vector<Protocol::Datapoint> ret;
|
vector<VNAData> ret;
|
||||||
if(input.size() > 1) {
|
if(input.size() > 1) {
|
||||||
int size = input.size();
|
int size = input.size();
|
||||||
double freqStep = 0.0;
|
double freqStep = 0.0;
|
||||||
@ -706,8 +687,8 @@ std::vector<Protocol::Datapoint> TwoThru::interpolateEvenFrequencySteps(std::vec
|
|||||||
// needs to interpolate
|
// needs to interpolate
|
||||||
double freq = freqStep;
|
double freq = freqStep;
|
||||||
while(freq <= input.back().frequency) {
|
while(freq <= input.back().frequency) {
|
||||||
Protocol::Datapoint interp;
|
VNAData interp;
|
||||||
auto it = lower_bound(input.begin(), input.end(), freq, [](const Protocol::Datapoint &lhs, const double f) -> bool {
|
auto it = lower_bound(input.begin(), input.end(), freq, [](const VNAData &lhs, const double f) -> bool {
|
||||||
return lhs.frequency < f;
|
return lhs.frequency < f;
|
||||||
});
|
});
|
||||||
if(it->frequency == freq) {
|
if(it->frequency == freq) {
|
||||||
@ -718,15 +699,14 @@ std::vector<Protocol::Datapoint> TwoThru::interpolateEvenFrequencySteps(std::vec
|
|||||||
it--;
|
it--;
|
||||||
auto low = *it;
|
auto low = *it;
|
||||||
double alpha = (freq - low.frequency) / (high.frequency - low.frequency);
|
double alpha = (freq - low.frequency) / (high.frequency - low.frequency);
|
||||||
interp.real_S11 = low.real_S11 * (1.0 - alpha) + high.real_S11 * alpha;
|
interp.S.m11 = low.S.m11 * (1.0 - alpha) + high.S.m11 * alpha;
|
||||||
interp.imag_S11 = low.imag_S11 * (1.0 - alpha) + high.imag_S11 * alpha;
|
interp.S.m12 = low.S.m12 * (1.0 - alpha) + high.S.m12 * alpha;
|
||||||
interp.real_S12 = low.real_S12 * (1.0 - alpha) + high.real_S12 * alpha;
|
interp.S.m21 = low.S.m21 * (1.0 - alpha) + high.S.m21 * alpha;
|
||||||
interp.imag_S12 = low.imag_S12 * (1.0 - alpha) + high.imag_S12 * alpha;
|
interp.S.m22 = low.S.m22 * (1.0 - alpha) + high.S.m22 * alpha;
|
||||||
interp.real_S21 = low.real_S21 * (1.0 - alpha) + high.real_S21 * alpha;
|
interp.cdbm = low.cdbm * (1.0 - alpha) + high.cdbm * alpha;
|
||||||
interp.imag_S21 = low.imag_S21 * (1.0 - alpha) + high.imag_S21 * alpha;
|
interp.reference_impedance = low.reference_impedance * (1.0 - alpha) + high.reference_impedance * alpha;
|
||||||
interp.real_S22 = low.real_S22 * (1.0 - alpha) + high.real_S22 * alpha;
|
|
||||||
interp.imag_S22 = low.imag_S22 * (1.0 - alpha) + high.imag_S22 * alpha;
|
|
||||||
}
|
}
|
||||||
|
interp.pointNum = it->pointNum;
|
||||||
interp.frequency = freq;
|
interp.frequency = freq;
|
||||||
ret.push_back(interp);
|
ret.push_back(interp);
|
||||||
freq += freqStep;
|
freq += freqStep;
|
||||||
|
@ -16,7 +16,7 @@ class TwoThru : public DeembeddingOption
|
|||||||
public:
|
public:
|
||||||
TwoThru();
|
TwoThru();
|
||||||
|
|
||||||
virtual void transformDatapoint(Protocol::Datapoint &p) override;
|
virtual void transformDatapoint(VNAData& p) override;
|
||||||
virtual void edit() override;
|
virtual void edit() override;
|
||||||
virtual Type getType() override {return DeembeddingOption::Type::TwoThru;}
|
virtual Type getType() override {return DeembeddingOption::Type::TwoThru;}
|
||||||
nlohmann::json toJSON() override;
|
nlohmann::json toJSON() override;
|
||||||
@ -25,19 +25,19 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void startMeasurement();
|
void startMeasurement();
|
||||||
void updateGUI();
|
void updateGUI();
|
||||||
void measurementCompleted(std::vector<Protocol::Datapoint> m) override;
|
void measurementCompleted(std::vector<VNAData> m) override;
|
||||||
private:
|
private:
|
||||||
using Point = struct {
|
using Point = struct {
|
||||||
double freq;
|
double freq;
|
||||||
Tparam inverseP1, inverseP2;
|
Tparam inverseP1, inverseP2;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<Protocol::Datapoint> interpolateEvenFrequencySteps(std::vector<Protocol::Datapoint> input);
|
static std::vector<VNAData> interpolateEvenFrequencySteps(std::vector<VNAData> input);
|
||||||
static std::vector<Point> calculateErrorBoxes(std::vector<Protocol::Datapoint> data_2xthru);
|
static std::vector<Point> calculateErrorBoxes(std::vector<VNAData> data_2xthru);
|
||||||
static std::vector<Point> calculateErrorBoxes(std::vector<Protocol::Datapoint> data_2xthru, std::vector<Protocol::Datapoint> data_fix_dut_fix, double z0);
|
static std::vector<Point> calculateErrorBoxes(std::vector<VNAData> data_2xthru, std::vector<VNAData> data_fix_dut_fix, double z0);
|
||||||
|
|
||||||
std::vector<Protocol::Datapoint> measurements2xthru;
|
std::vector<VNAData> measurements2xthru;
|
||||||
std::vector<Protocol::Datapoint> measurementsDUT;
|
std::vector<VNAData> measurementsDUT;
|
||||||
double Z0;
|
double Z0;
|
||||||
std::vector<Point> points;
|
std::vector<Point> points;
|
||||||
bool measuring2xthru;
|
bool measuring2xthru;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "Deembedding/manualdeembeddingdialog.h"
|
#include "Deembedding/manualdeembeddingdialog.h"
|
||||||
#include "Calibration/manualcalibrationdialog.h"
|
#include "Calibration/manualcalibrationdialog.h"
|
||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
|
#include "Tools/parameters.h"
|
||||||
|
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
@ -812,28 +813,30 @@ void VNA::NewDatapoint(Protocol::Datapoint d)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
d = average.process(d);
|
auto vd = VNAData(d);
|
||||||
|
|
||||||
|
vd = average.process(vd);
|
||||||
if(calMeasuring) {
|
if(calMeasuring) {
|
||||||
if(average.currentSweep() == averages) {
|
if(average.currentSweep() == averages) {
|
||||||
// this is the last averaging sweep, use values for calibration
|
// this is the last averaging sweep, use values for calibration
|
||||||
if(!calWaitFirst || d.pointNum == 0) {
|
if(!calWaitFirst || vd.pointNum == 0) {
|
||||||
calWaitFirst = false;
|
calWaitFirst = false;
|
||||||
cal.addMeasurements(calMeasurements, d);
|
cal.addMeasurements(calMeasurements, vd);
|
||||||
if(d.pointNum == settings.npoints - 1) {
|
if(vd.pointNum == settings.npoints - 1) {
|
||||||
calMeasuring = false;
|
calMeasuring = false;
|
||||||
emit CalibrationMeasurementsComplete(calMeasurements);
|
emit CalibrationMeasurementsComplete(calMeasurements);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int percentage = (((average.currentSweep() - 1) * 100) + (d.pointNum + 1) * 100 / settings.npoints) / averages;
|
int percentage = (((average.currentSweep() - 1) * 100) + (vd.pointNum + 1) * 100 / settings.npoints) / averages;
|
||||||
calDialog.setValue(percentage);
|
calDialog.setValue(percentage);
|
||||||
}
|
}
|
||||||
if(calValid) {
|
if(calValid) {
|
||||||
cal.correctMeasurement(d);
|
cal.correctMeasurement(vd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(deembedding_active) {
|
if(deembedding_active) {
|
||||||
deembedding.Deembed(d);
|
deembedding.Deembed(vd);
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceMath::DataType type;
|
TraceMath::DataType type;
|
||||||
@ -847,17 +850,17 @@ void VNA::NewDatapoint(Protocol::Datapoint d)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
traceModel.addVNAData(d, type);
|
traceModel.addVNAData(vd, type);
|
||||||
emit dataChanged();
|
emit dataChanged();
|
||||||
if(d.pointNum == settings.npoints - 1) {
|
if(vd.pointNum == settings.npoints - 1) {
|
||||||
UpdateAverageCount();
|
UpdateAverageCount();
|
||||||
markerModel->updateMarkers();
|
markerModel->updateMarkers();
|
||||||
}
|
}
|
||||||
static unsigned int lastPoint = 0;
|
static unsigned int lastPoint = 0;
|
||||||
if(d.pointNum > 0 && d.pointNum != lastPoint + 1) {
|
if(vd.pointNum > 0 && vd.pointNum != lastPoint + 1) {
|
||||||
qWarning() << "Got point" << d.pointNum << "but last received point was" << lastPoint << "("<<(d.pointNum-lastPoint-1)<<"missed points)";
|
qWarning() << "Got point" << vd.pointNum << "but last received point was" << lastPoint << "("<<(vd.pointNum-lastPoint-1)<<"missed points)";
|
||||||
}
|
}
|
||||||
lastPoint = d.pointNum;
|
lastPoint = vd.pointNum;
|
||||||
|
|
||||||
if (needsSegmentUpdate) {
|
if (needsSegmentUpdate) {
|
||||||
changingSettings = true;
|
changingSettings = true;
|
||||||
|
29
Software/PC_Application/VNA/vnadata.h
Normal file
29
Software/PC_Application/VNA/vnadata.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef VNADATA_H
|
||||||
|
#define VNADATA_H
|
||||||
|
|
||||||
|
#include "Tools/parameters.h"
|
||||||
|
|
||||||
|
#include <complex>
|
||||||
|
|
||||||
|
class VNAData {
|
||||||
|
public:
|
||||||
|
VNAData() = default;
|
||||||
|
VNAData(const Protocol::Datapoint &d) {
|
||||||
|
S = Sparam(std::complex<double>(d.real_S11, d.imag_S11),
|
||||||
|
std::complex<double>(d.real_S12, d.imag_S12),
|
||||||
|
std::complex<double>(d.real_S21, d.imag_S21),
|
||||||
|
std::complex<double>(d.real_S22, d.imag_S22));
|
||||||
|
frequency = d.frequency;
|
||||||
|
cdbm = d.cdbm;
|
||||||
|
pointNum = d.pointNum;
|
||||||
|
reference_impedance = 50.0;
|
||||||
|
}
|
||||||
|
double frequency;
|
||||||
|
int cdbm;
|
||||||
|
Sparam S;
|
||||||
|
unsigned int pointNum;
|
||||||
|
double reference_impedance;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VNADATA_H
|
@ -22,12 +22,12 @@ void Averaging::setAverages(unsigned int a)
|
|||||||
reset(avg.size());
|
reset(avg.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol::Datapoint Averaging::process(Protocol::Datapoint d)
|
VNAData Averaging::process(VNAData d)
|
||||||
{
|
{
|
||||||
auto S11 = complex<double>(d.real_S11, d.imag_S11);
|
auto S11 = d.S.m11;
|
||||||
auto S12 = complex<double>(d.real_S12, d.imag_S12);
|
auto S12 = d.S.m12;
|
||||||
auto S21 = complex<double>(d.real_S21, d.imag_S21);
|
auto S21 = d.S.m21;
|
||||||
auto S22 = complex<double>(d.real_S22, d.imag_S22);
|
auto S22 = d.S.m22;
|
||||||
|
|
||||||
if (d.pointNum == avg.size()) {
|
if (d.pointNum == avg.size()) {
|
||||||
// add moving average entry
|
// add moving average entry
|
||||||
@ -99,14 +99,7 @@ Protocol::Datapoint Averaging::process(Protocol::Datapoint d)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d.real_S11 = S11.real();
|
d.S = Sparam(S11, S12, S21, S22);
|
||||||
d.imag_S11 = S11.imag();
|
|
||||||
d.real_S12 = S12.real();
|
|
||||||
d.imag_S12 = S12.imag();
|
|
||||||
d.real_S21 = S21.real();
|
|
||||||
d.imag_S21 = S21.imag();
|
|
||||||
d.real_S22 = S22.real();
|
|
||||||
d.imag_S22 = S22.imag();
|
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define AVERAGING_H
|
#define AVERAGING_H
|
||||||
|
|
||||||
#include "Device/device.h"
|
#include "Device/device.h"
|
||||||
|
#include "VNA/vnadata.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
@ -18,7 +19,7 @@ public:
|
|||||||
Averaging();
|
Averaging();
|
||||||
void reset(unsigned int points);
|
void reset(unsigned int points);
|
||||||
void setAverages(unsigned int a);
|
void setAverages(unsigned int a);
|
||||||
Protocol::Datapoint process(Protocol::Datapoint d);
|
VNAData process(VNAData d);
|
||||||
Protocol::SpectrumAnalyzerResult process(Protocol::SpectrumAnalyzerResult d);
|
Protocol::SpectrumAnalyzerResult process(Protocol::SpectrumAnalyzerResult d);
|
||||||
// Returns the number of averaged sweeps. Value is incremented whenever the last point of the sweep is added.
|
// Returns the number of averaged sweeps. Value is incremented whenever the last point of the sweep is added.
|
||||||
// Returned values are in range 0 to averages
|
// Returned values are in range 0 to averages
|
||||||
|
@ -88,9 +88,6 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
|
|||||||
ui->StartupSARBW->setPrefixes(" k");
|
ui->StartupSARBW->setPrefixes(" k");
|
||||||
|
|
||||||
// Acquisition page
|
// Acquisition page
|
||||||
ui->AcquisitionReferenceImpedance->setUnit("Ω");
|
|
||||||
ui->AcquisitionReferenceImpedance->setPrefixes(" ");
|
|
||||||
ui->AcquisitionReferenceImpedance->setPrecision(3);
|
|
||||||
ui->AcquisitionDFTlimitRBW->setUnit("Hz");
|
ui->AcquisitionDFTlimitRBW->setUnit("Hz");
|
||||||
ui->AcquisitionDFTlimitRBW->setPrefixes(" k");
|
ui->AcquisitionDFTlimitRBW->setPrefixes(" k");
|
||||||
connect(ui->AcquisitionUseDFT, &QCheckBox::toggled, [=](bool enabled) {
|
connect(ui->AcquisitionUseDFT, &QCheckBox::toggled, [=](bool enabled) {
|
||||||
@ -237,7 +234,6 @@ void PreferencesDialog::setInitialGUIState()
|
|||||||
ui->AcquisitionAdjustPowerLevel->setChecked(p->Acquisition.adjustPowerLevel);
|
ui->AcquisitionAdjustPowerLevel->setChecked(p->Acquisition.adjustPowerLevel);
|
||||||
ui->AcquisitionUseHarmonic->setChecked(p->Acquisition.harmonicMixing);
|
ui->AcquisitionUseHarmonic->setChecked(p->Acquisition.harmonicMixing);
|
||||||
ui->AcquisitionAllowSegmentedSweep->setChecked(p->Acquisition.allowSegmentedSweep);
|
ui->AcquisitionAllowSegmentedSweep->setChecked(p->Acquisition.allowSegmentedSweep);
|
||||||
ui->AcquisitionReferenceImpedance->setValue(p->Acquisition.refImp);
|
|
||||||
ui->AcquisitionUseDFT->setChecked(p->Acquisition.useDFTinSAmode);
|
ui->AcquisitionUseDFT->setChecked(p->Acquisition.useDFTinSAmode);
|
||||||
ui->AcquisitionDFTlimitRBW->setValue(p->Acquisition.RBWLimitForDFT);
|
ui->AcquisitionDFTlimitRBW->setValue(p->Acquisition.RBWLimitForDFT);
|
||||||
ui->AcquisitionAveragingMode->setCurrentIndex(p->Acquisition.useMedianAveraging ? 1 : 0);
|
ui->AcquisitionAveragingMode->setCurrentIndex(p->Acquisition.useMedianAveraging ? 1 : 0);
|
||||||
@ -298,7 +294,6 @@ void PreferencesDialog::updateFromGUI()
|
|||||||
p->Acquisition.adjustPowerLevel = ui->AcquisitionAdjustPowerLevel->isChecked();
|
p->Acquisition.adjustPowerLevel = ui->AcquisitionAdjustPowerLevel->isChecked();
|
||||||
p->Acquisition.harmonicMixing = ui->AcquisitionUseHarmonic->isChecked();
|
p->Acquisition.harmonicMixing = ui->AcquisitionUseHarmonic->isChecked();
|
||||||
p->Acquisition.allowSegmentedSweep = ui->AcquisitionAllowSegmentedSweep->isChecked();
|
p->Acquisition.allowSegmentedSweep = ui->AcquisitionAllowSegmentedSweep->isChecked();
|
||||||
p->Acquisition.refImp = ui->AcquisitionReferenceImpedance->value();
|
|
||||||
p->Acquisition.useDFTinSAmode = ui->AcquisitionUseDFT->isChecked();
|
p->Acquisition.useDFTinSAmode = ui->AcquisitionUseDFT->isChecked();
|
||||||
p->Acquisition.RBWLimitForDFT = ui->AcquisitionDFTlimitRBW->value();
|
p->Acquisition.RBWLimitForDFT = ui->AcquisitionDFTlimitRBW->value();
|
||||||
p->Acquisition.useMedianAveraging = ui->AcquisitionAveragingMode->currentIndex() == 1;
|
p->Acquisition.useMedianAveraging = ui->AcquisitionAveragingMode->currentIndex() == 1;
|
||||||
|
@ -73,7 +73,6 @@ public:
|
|||||||
bool useDFTinSAmode;
|
bool useDFTinSAmode;
|
||||||
double RBWLimitForDFT;
|
double RBWLimitForDFT;
|
||||||
bool useMedianAveraging;
|
bool useMedianAveraging;
|
||||||
double refImp; // reference impedance
|
|
||||||
|
|
||||||
// advanced, hardware specific settings
|
// advanced, hardware specific settings
|
||||||
double IF1;
|
double IF1;
|
||||||
@ -153,7 +152,6 @@ private:
|
|||||||
{&Acquisition.useDFTinSAmode, "Acquisition.useDFTinSAmode", true},
|
{&Acquisition.useDFTinSAmode, "Acquisition.useDFTinSAmode", true},
|
||||||
{&Acquisition.RBWLimitForDFT, "Acquisition.RBWLimitForDFT", 3000.0},
|
{&Acquisition.RBWLimitForDFT, "Acquisition.RBWLimitForDFT", 3000.0},
|
||||||
{&Acquisition.useMedianAveraging, "Acquisition.useMedianAveraging", false},
|
{&Acquisition.useMedianAveraging, "Acquisition.useMedianAveraging", false},
|
||||||
{&Acquisition.refImp, "Acquisition.referenceImpedance", 50.0},
|
|
||||||
{&Acquisition.IF1, "Acquisition.IF1", 62000000},
|
{&Acquisition.IF1, "Acquisition.IF1", 62000000},
|
||||||
{&Acquisition.ADCprescaler, "Acquisition.ADCprescaler", 128},
|
{&Acquisition.ADCprescaler, "Acquisition.ADCprescaler", 128},
|
||||||
{&Acquisition.DFTPhaseInc, "Acquisition.DFTPhaseInc", 1280},
|
{&Acquisition.DFTPhaseInc, "Acquisition.DFTPhaseInc", 1280},
|
||||||
|
@ -745,24 +745,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<layout class="QFormLayout" name="formLayout_11">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_39">
|
|
||||||
<property name="text">
|
|
||||||
<string>Reference impedance:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="SIUnitEdit" name="AcquisitionReferenceImpedance">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>Frequency of the first IF</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -16,6 +16,7 @@ using namespace std;
|
|||||||
Touchstone::Touchstone(unsigned int ports)
|
Touchstone::Touchstone(unsigned int ports)
|
||||||
{
|
{
|
||||||
this->m_ports = ports;
|
this->m_ports = ports;
|
||||||
|
referenceImpedance = 50.0;
|
||||||
m_datapoints.clear();
|
m_datapoints.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,8 +75,8 @@ stringstream Touchstone::toString(Touchstone::Scale unit, Touchstone::Format for
|
|||||||
case Format::RealImaginary: s << "RI "; break;
|
case Format::RealImaginary: s << "RI "; break;
|
||||||
case Format::MagnitudeAngle: s << "MA "; break;
|
case Format::MagnitudeAngle: s << "MA "; break;
|
||||||
}
|
}
|
||||||
// reference impedance is always 50 ohm
|
// reference impedance
|
||||||
s << "R 50\n";
|
s << "R " << referenceImpedance << "\n";
|
||||||
|
|
||||||
auto printParameter = [format](ostream &out, complex<double> &c) {
|
auto printParameter = [format](ostream &out, complex<double> &c) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
@ -192,10 +193,8 @@ Touchstone Touchstone::fromFile(string filename)
|
|||||||
for(;iss>>s;) {
|
for(;iss>>s;) {
|
||||||
if(last_R) {
|
if(last_R) {
|
||||||
last_R = false;
|
last_R = false;
|
||||||
// check reference impedance
|
// read reference impedance
|
||||||
if (stoi(s, nullptr, 10) != 50) {
|
ret.referenceImpedance = stod(s, nullptr);
|
||||||
throw runtime_error("Invalid reference impedance, only 50Ohm is supported");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!s.compare("HZ")) {
|
if (!s.compare("HZ")) {
|
||||||
@ -438,3 +437,13 @@ void Touchstone::fromJSON(nlohmann::json j)
|
|||||||
m_datapoints.push_back(d);
|
m_datapoints.push_back(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Touchstone::getReferenceImpedance() const
|
||||||
|
{
|
||||||
|
return referenceImpedance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Touchstone::setReferenceImpedance(double value)
|
||||||
|
{
|
||||||
|
referenceImpedance = value;
|
||||||
|
}
|
||||||
|
@ -51,8 +51,12 @@ public:
|
|||||||
virtual nlohmann::json toJSON();
|
virtual nlohmann::json toJSON();
|
||||||
virtual void fromJSON(nlohmann::json j);
|
virtual void fromJSON(nlohmann::json j);
|
||||||
|
|
||||||
|
double getReferenceImpedance() const;
|
||||||
|
void setReferenceImpedance(double value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_ports;
|
unsigned int m_ports;
|
||||||
|
double referenceImpedance;
|
||||||
std::vector<Datapoint> m_datapoints;
|
std::vector<Datapoint> m_datapoints;
|
||||||
QString filename;
|
QString filename;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user