use json for calibration file format, allow male/female standard selection
This commit is contained in:
parent
55ac50ee84
commit
93ad894de6
@ -26,6 +26,7 @@ Calibration::Calibration()
|
|||||||
measurements[Measurement::Line].datapoints = vector<Protocol::Datapoint>();
|
measurements[Measurement::Line].datapoints = vector<Protocol::Datapoint>();
|
||||||
|
|
||||||
type = Type::None;
|
type = Type::None;
|
||||||
|
port1Standard = port2Standard = PortStandard::Male;
|
||||||
}
|
}
|
||||||
|
|
||||||
Calibration::Standard Calibration::getPort1Standard(Calibration::Measurement m)
|
Calibration::Standard Calibration::getPort1Standard(Calibration::Measurement m)
|
||||||
@ -124,7 +125,7 @@ bool Calibration::constructErrorTerms(Calibration::Type type)
|
|||||||
bool isTRL = type == Type::TRL;
|
bool isTRL = type == Type::TRL;
|
||||||
bool uses_male = true;
|
bool uses_male = true;
|
||||||
bool uses_female = true;
|
bool uses_female = true;
|
||||||
if(kit.checkIfValid(minFreq, maxFreq, isTRL, uses_male, uses_female)) {
|
if(!kit.checkIfValid(minFreq, maxFreq, isTRL, uses_male, uses_female)) {
|
||||||
// TODO adjust for male/female standards
|
// TODO adjust for male/female standards
|
||||||
// Calkit does not support complete calibration range
|
// Calkit does not support complete calibration range
|
||||||
QString msg = QString("The calibration kit does not support the complete span.\n\n")
|
QString msg = QString("The calibration kit does not support the complete span.\n\n")
|
||||||
@ -135,6 +136,11 @@ bool Calibration::constructErrorTerms(Calibration::Type type)
|
|||||||
qWarning() << msg;
|
qWarning() << msg;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// check calkit standards and adjust if necessary
|
||||||
|
if(!kit.hasSeparateMaleFemaleStandards()) {
|
||||||
|
port1Standard = PortStandard::Male;
|
||||||
|
port2Standard = PortStandard::Male;
|
||||||
|
}
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case Type::Port1SOL: constructPort1SOL(); break;
|
case Type::Port1SOL: constructPort1SOL(); break;
|
||||||
case Type::Port2SOL: constructPort2SOL(); break;
|
case Type::Port2SOL: constructPort2SOL(); break;
|
||||||
@ -182,7 +188,7 @@ void Calibration::construct12TermPoints()
|
|||||||
auto S22_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S22, measurements[Measurement::Through].datapoints[i].imag_S22);
|
auto S22_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S22, measurements[Measurement::Through].datapoints[i].imag_S22);
|
||||||
auto S12_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S12, measurements[Measurement::Through].datapoints[i].imag_S12);
|
auto S12_through = complex<double>(measurements[Measurement::Through].datapoints[i].real_S12, measurements[Measurement::Through].datapoints[i].imag_S12);
|
||||||
|
|
||||||
auto actual = kit.toSOLT(p.frequency);
|
auto actual = kit.toSOLT(p.frequency, port1Standard == PortStandard::Male);
|
||||||
// Forward calibration
|
// Forward calibration
|
||||||
computeSOL(S11_short, S11_open, S11_load, p.fe00, p.fe11, p.fe10e01, actual.Open, actual.Short, actual.Load);
|
computeSOL(S11_short, S11_open, S11_load, p.fe00, p.fe11, p.fe10e01, actual.Open, actual.Short, actual.Load);
|
||||||
p.fe30 = S21_isolation;
|
p.fe30 = S21_isolation;
|
||||||
@ -193,6 +199,7 @@ void Calibration::construct12TermPoints()
|
|||||||
/ ((S11_through - p.fe00)*(actual.ThroughS22-p.fe11*deltaS)-deltaS*p.fe10e01);
|
/ ((S11_through - p.fe00)*(actual.ThroughS22-p.fe11*deltaS)-deltaS*p.fe10e01);
|
||||||
p.fe10e32 = (S21_through - p.fe30)*(1.0 - p.fe11*actual.ThroughS11 - p.fe22*actual.ThroughS22 + p.fe11*p.fe22*deltaS) / actual.ThroughS21;
|
p.fe10e32 = (S21_through - p.fe30)*(1.0 - p.fe11*actual.ThroughS11 - p.fe22*actual.ThroughS22 + p.fe11*p.fe22*deltaS) / actual.ThroughS21;
|
||||||
// Reverse calibration
|
// Reverse calibration
|
||||||
|
actual = kit.toSOLT(p.frequency, port2Standard == PortStandard::Male);
|
||||||
computeSOL(S22_short, S22_open, S22_load, p.re33, p.re22, p.re23e32, actual.Open, actual.Short, actual.Load);
|
computeSOL(S22_short, S22_open, S22_load, p.re33, p.re22, p.re23e32, actual.Open, actual.Short, actual.Load);
|
||||||
p.re03 = S12_isolation;
|
p.re03 = S12_isolation;
|
||||||
p.re11 = ((S22_through - p.re33)*(1.0 - p.re22 * actual.ThroughS22)-actual.ThroughS22*p.re23e32)
|
p.re11 = ((S22_through - p.re33)*(1.0 - p.re22 * actual.ThroughS22)-actual.ThroughS22*p.re23e32)
|
||||||
@ -213,7 +220,7 @@ void Calibration::constructPort1SOL()
|
|||||||
auto S11_short = complex<double>(measurements[Measurement::Port1Short].datapoints[i].real_S11, measurements[Measurement::Port1Short].datapoints[i].imag_S11);
|
auto S11_short = complex<double>(measurements[Measurement::Port1Short].datapoints[i].real_S11, measurements[Measurement::Port1Short].datapoints[i].imag_S11);
|
||||||
auto S11_load = complex<double>(measurements[Measurement::Port1Load].datapoints[i].real_S11, measurements[Measurement::Port1Load].datapoints[i].imag_S11);
|
auto S11_load = complex<double>(measurements[Measurement::Port1Load].datapoints[i].real_S11, measurements[Measurement::Port1Load].datapoints[i].imag_S11);
|
||||||
// OSL port1
|
// OSL port1
|
||||||
auto actual = kit.toSOLT(p.frequency);
|
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
|
||||||
computeSOL(S11_short, S11_open, S11_load, p.fe00, p.fe11, p.fe10e01, actual.Open, actual.Short, actual.Load);
|
computeSOL(S11_short, S11_open, S11_load, p.fe00, p.fe11, p.fe10e01, actual.Open, actual.Short, actual.Load);
|
||||||
// All other calibration coefficients to ideal values
|
// All other calibration coefficients to ideal values
|
||||||
@ -241,7 +248,7 @@ void Calibration::constructPort2SOL()
|
|||||||
auto S22_short = complex<double>(measurements[Measurement::Port2Short].datapoints[i].real_S22, measurements[Measurement::Port2Short].datapoints[i].imag_S22);
|
auto S22_short = complex<double>(measurements[Measurement::Port2Short].datapoints[i].real_S22, measurements[Measurement::Port2Short].datapoints[i].imag_S22);
|
||||||
auto S22_load = complex<double>(measurements[Measurement::Port2Load].datapoints[i].real_S22, measurements[Measurement::Port2Load].datapoints[i].imag_S22);
|
auto S22_load = complex<double>(measurements[Measurement::Port2Load].datapoints[i].real_S22, measurements[Measurement::Port2Load].datapoints[i].imag_S22);
|
||||||
// OSL port2
|
// OSL port2
|
||||||
auto actual = kit.toSOLT(p.frequency);
|
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
|
||||||
computeSOL(S22_short, S22_open, S22_load, p.re33, p.re22, p.re23e32, actual.Open, actual.Short, actual.Load);
|
computeSOL(S22_short, S22_open, S22_load, p.re33, p.re22, p.re23e32, actual.Open, actual.Short, actual.Load);
|
||||||
// All other calibration coefficients to ideal values
|
// All other calibration coefficients to ideal values
|
||||||
@ -775,11 +782,23 @@ bool Calibration::openFromFile(QString filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
file >> *this;
|
nlohmann::json j;
|
||||||
|
file >> j;
|
||||||
|
fromJSON(j);
|
||||||
} catch(exception e) {
|
} catch(exception e) {
|
||||||
InformationBox::ShowError("File parsing error", e.what());
|
// json parsing failed, probably using a legacy file format
|
||||||
qWarning() << "Calibration file parsing failed: " << e.what();
|
try {
|
||||||
return false;
|
file.clear();
|
||||||
|
file.seekg(0);
|
||||||
|
file >> *this;
|
||||||
|
InformationBox::ShowMessage("Loading calibration file", "The file \"" + filename + "\" is stored in a deprecated"
|
||||||
|
" calibration format. Future versions of this application might not support"
|
||||||
|
" it anymore. Please save the calibration kit to update to the new format");
|
||||||
|
} catch(exception e) {
|
||||||
|
InformationBox::ShowError("File parsing error", e.what());
|
||||||
|
qWarning() << "Calibration file parsing failed: " << e.what();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this->currentCalFile = filename; // if all ok, remember this
|
this->currentCalFile = filename; // if all ok, remember this
|
||||||
|
|
||||||
@ -803,7 +822,7 @@ bool Calibration::saveToFile(QString filename)
|
|||||||
auto calibration_file = filename + ".cal";
|
auto calibration_file = filename + ".cal";
|
||||||
ofstream file;
|
ofstream file;
|
||||||
file.open(calibration_file.toStdString());
|
file.open(calibration_file.toStdString());
|
||||||
file << *this;
|
file << setw(1) << toJSON();
|
||||||
|
|
||||||
auto calkit_file = filename + ".calkit";
|
auto calkit_file = filename + ".calkit";
|
||||||
qDebug() << "Saving associated calibration kit to file" << calkit_file;
|
qDebug() << "Saving associated calibration kit to file" << calkit_file;
|
||||||
@ -849,6 +868,95 @@ double Calibration::getMaxFreq(){
|
|||||||
int Calibration::getNumPoints(){
|
int Calibration::getNumPoints(){
|
||||||
return this->points.size();
|
return this->points.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nlohmann::json Calibration::toJSON()
|
||||||
|
{
|
||||||
|
nlohmann::json j;
|
||||||
|
nlohmann::json j_measurements;
|
||||||
|
for(auto m : measurements) {
|
||||||
|
if(m.second.datapoints.size() > 0) {
|
||||||
|
nlohmann::json j_measurement;
|
||||||
|
j_measurement["name"] = MeasurementToString(m.first).toStdString();
|
||||||
|
j_measurement["timestamp"] = m.second.timestamp.toSecsSinceEpoch();
|
||||||
|
nlohmann::json j_points;
|
||||||
|
for(auto p : m.second.datapoints) {
|
||||||
|
nlohmann::json j_point;
|
||||||
|
j_point["frequency"] = p.frequency;
|
||||||
|
j_point["S11_real"] = p.real_S11;
|
||||||
|
j_point["S11_imag"] = p.imag_S11;
|
||||||
|
j_point["S12_real"] = p.real_S12;
|
||||||
|
j_point["S12_imag"] = p.imag_S12;
|
||||||
|
j_point["S21_real"] = p.real_S21;
|
||||||
|
j_point["S21_imag"] = p.imag_S21;
|
||||||
|
j_point["S22_real"] = p.real_S22;
|
||||||
|
j_point["S22_imag"] = p.imag_S22;
|
||||||
|
j_points.push_back(j_point);
|
||||||
|
}
|
||||||
|
j_measurement["points"] = j_points;
|
||||||
|
j_measurements.push_back(j_measurement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
j["measurements"] = j_measurements;
|
||||||
|
j["type"] = TypeToString(getType()).toStdString();
|
||||||
|
j["port1StandardMale"] = port1Standard == PortStandard::Male;
|
||||||
|
j["port2StandardMale"] = port2Standard == PortStandard::Male;
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Calibration::fromJSON(nlohmann::json j)
|
||||||
|
{
|
||||||
|
clearMeasurements();
|
||||||
|
resetErrorTerms();
|
||||||
|
port1Standard = j.value("port1StandardMale", true) ? PortStandard::Male : PortStandard::Female;
|
||||||
|
port2Standard = j.value("port2StandardMale", true) ? PortStandard::Male : PortStandard::Female;
|
||||||
|
if(j.contains("measurements")) {
|
||||||
|
// grab measurements
|
||||||
|
for(auto j_m : j["measurements"]) {
|
||||||
|
if(!j_m.contains("name")) {
|
||||||
|
throw runtime_error("Measurement without name given");
|
||||||
|
}
|
||||||
|
auto m = MeasurementFromString(QString::fromStdString(j_m["name"]));
|
||||||
|
if(m == Measurement::Last) {
|
||||||
|
throw runtime_error("Measurement name unknown: "+std::string(j_m["name"]));
|
||||||
|
}
|
||||||
|
// get timestamp
|
||||||
|
measurements[m].timestamp = QDateTime::fromSecsSinceEpoch(j_m.value("timestamp", 0));
|
||||||
|
// extract points
|
||||||
|
if(!j_m.contains("points")) {
|
||||||
|
throw runtime_error("Measurement "+MeasurementToString(m).toStdString()+" does not contain any points");
|
||||||
|
}
|
||||||
|
int pointNum = 0;
|
||||||
|
for(auto j_p : j_m["points"]) {
|
||||||
|
Protocol::Datapoint p;
|
||||||
|
p.pointNum = pointNum++;
|
||||||
|
p.frequency = j_p.value("frequency", 0.0);
|
||||||
|
p.real_S11 = j_p.value("S11_real", 0.0);
|
||||||
|
p.imag_S11 = j_p.value("S11_imag", 0.0);
|
||||||
|
p.real_S12 = j_p.value("S12_real", 0.0);
|
||||||
|
p.imag_S12 = j_p.value("S12_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// got all measurements, construct calibration according to type
|
||||||
|
if(j.contains("type")) {
|
||||||
|
auto t = TypeFromString(QString::fromStdString(j["type"]));
|
||||||
|
if(t == Type::Last) {
|
||||||
|
throw runtime_error("Calibration type unknown: "+std::string(j["type"]));
|
||||||
|
}
|
||||||
|
if(calculationPossible(t)) {
|
||||||
|
constructErrorTerms(t);
|
||||||
|
} else {
|
||||||
|
throw runtime_error("Incomplete calibration data, the requested calibration could not be performed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString Calibration::getCurrentCalibrationFile(){
|
QString Calibration::getCurrentCalibrationFile(){
|
||||||
return this->currentCalFile;
|
return this->currentCalFile;
|
||||||
}
|
}
|
||||||
@ -912,6 +1020,9 @@ istream& operator >>(istream &in, Calibration &c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// old file format did not contain port standard gender, set default
|
||||||
|
c.port1Standard = Calibration::PortStandard::Male;
|
||||||
|
c.port2Standard = Calibration::PortStandard::Male;
|
||||||
qDebug() << "Calibration file parsing complete";
|
qDebug() << "Calibration file parsing complete";
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
@ -1018,6 +1129,26 @@ void Calibration::setCalibrationKit(const Calkit &value)
|
|||||||
kit = value;
|
kit = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Calibration::setPortStandard(int port, Calibration::PortStandard standard)
|
||||||
|
{
|
||||||
|
if(port == 1) {
|
||||||
|
port1Standard = standard;
|
||||||
|
} else if(port == 2) {
|
||||||
|
port2Standard = standard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Calibration::PortStandard Calibration::getPortStandard(int port)
|
||||||
|
{
|
||||||
|
if(port == 1) {
|
||||||
|
return port1Standard;
|
||||||
|
} else if(port == 2) {
|
||||||
|
return port2Standard;
|
||||||
|
} else {
|
||||||
|
return PortStandard::Male;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Calibration::Type Calibration::getType() const
|
Calibration::Type Calibration::getType() const
|
||||||
{
|
{
|
||||||
return type;
|
return type;
|
||||||
|
@ -11,8 +11,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <savable.h>
|
||||||
|
|
||||||
class Calibration
|
class Calibration : public Savable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Calibration();
|
Calibration();
|
||||||
@ -108,6 +109,21 @@ public:
|
|||||||
Calkit& getCalibrationKit();
|
Calkit& getCalibrationKit();
|
||||||
void setCalibrationKit(const Calkit &value);
|
void setCalibrationKit(const Calkit &value);
|
||||||
|
|
||||||
|
enum class PortStandard {
|
||||||
|
Male,
|
||||||
|
Female,
|
||||||
|
};
|
||||||
|
void setPortStandard(int port, PortStandard standard);
|
||||||
|
PortStandard getPortStandard(int port);
|
||||||
|
|
||||||
|
QString getCurrentCalibrationFile();
|
||||||
|
double getMinFreq();
|
||||||
|
double getMaxFreq();
|
||||||
|
int getNumPoints();
|
||||||
|
|
||||||
|
nlohmann::json toJSON() override;
|
||||||
|
void fromJSON(nlohmann::json j) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void construct12TermPoints();
|
void construct12TermPoints();
|
||||||
void constructPort1SOL();
|
void constructPort1SOL();
|
||||||
@ -157,14 +173,9 @@ private:
|
|||||||
|
|
||||||
Calkit kit;
|
Calkit kit;
|
||||||
QString descriptiveCalName();
|
QString descriptiveCalName();
|
||||||
|
|
||||||
private:
|
|
||||||
QString currentCalFile;
|
QString currentCalFile;
|
||||||
public:
|
|
||||||
QString getCurrentCalibrationFile();
|
PortStandard port1Standard, port2Standard;
|
||||||
double getMinFreq();
|
|
||||||
double getMaxFreq();
|
|
||||||
int getNumPoints();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CALIBRATION_H
|
#endif // CALIBRATION_H
|
||||||
|
@ -26,6 +26,45 @@ CalibrationTraceDialog::CalibrationTraceDialog(Calibration *cal, double f_min, d
|
|||||||
ui->tableView->setColumnWidth(3, 160);
|
ui->tableView->setColumnWidth(3, 160);
|
||||||
UpdateCalibrationStatus();
|
UpdateCalibrationStatus();
|
||||||
|
|
||||||
|
connect(ui->port1Group, qOverload<int>(&QButtonGroup::buttonClicked), [=](){
|
||||||
|
if(ui->port1Male->isChecked()) {
|
||||||
|
cal->setPortStandard(1, Calibration::PortStandard::Male);
|
||||||
|
} else {
|
||||||
|
cal->setPortStandard(1, Calibration::PortStandard::Female);
|
||||||
|
}
|
||||||
|
UpdateCalibrationStatus();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->port2Group, qOverload<int>(&QButtonGroup::buttonClicked), [=](){
|
||||||
|
if(ui->port2Male->isChecked()) {
|
||||||
|
cal->setPortStandard(2, Calibration::PortStandard::Male);
|
||||||
|
} else {
|
||||||
|
cal->setPortStandard(2, Calibration::PortStandard::Female);
|
||||||
|
}
|
||||||
|
UpdateCalibrationStatus();
|
||||||
|
});
|
||||||
|
|
||||||
|
// hide selector if calkit does not have separate male/female standards
|
||||||
|
if(!cal->getCalibrationKit().hasSeparateMaleFemaleStandards()) {
|
||||||
|
ui->port1Standards->hide();
|
||||||
|
ui->port2Standards->hide();
|
||||||
|
// default selection is male
|
||||||
|
ui->port1Male->click();
|
||||||
|
ui->port2Male->click();
|
||||||
|
} else {
|
||||||
|
// separate standards defined
|
||||||
|
if(cal->getPortStandard(1) == Calibration::PortStandard::Male) {
|
||||||
|
ui->port1Male->setChecked(true);
|
||||||
|
} else {
|
||||||
|
ui->port1Female->setChecked(true);
|
||||||
|
}
|
||||||
|
if(cal->getPortStandard(2) == Calibration::PortStandard::Male) {
|
||||||
|
ui->port2Male->setChecked(true);
|
||||||
|
} else {
|
||||||
|
ui->port2Female->setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check calibration kit span
|
// Check calibration kit span
|
||||||
if(type != Calibration::Type::None) {
|
if(type != Calibration::Type::None) {
|
||||||
auto kit = cal->getCalibrationKit();
|
auto kit = cal->getCalibrationKit();
|
||||||
|
@ -16,80 +16,151 @@
|
|||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTableView" name="tableView">
|
<widget class="QGroupBox" name="port1Standards">
|
||||||
<property name="selectionBehavior">
|
<property name="title">
|
||||||
<enum>QAbstractItemView::SelectRows</enum>
|
<string>Port 1 Standards</string>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="horizontalHeaderCascadingSectionResizes">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<bool>true</bool>
|
<item>
|
||||||
</attribute>
|
<widget class="QRadioButton" name="port1Male">
|
||||||
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
|
<property name="text">
|
||||||
<bool>false</bool>
|
<string>Male</string>
|
||||||
</attribute>
|
</property>
|
||||||
<attribute name="horizontalHeaderStretchLastSection">
|
<attribute name="buttonGroup">
|
||||||
<bool>true</bool>
|
<string notr="true">port1Group</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<attribute name="verticalHeaderVisible">
|
</widget>
|
||||||
<bool>false</bool>
|
</item>
|
||||||
</attribute>
|
<item>
|
||||||
<attribute name="verticalHeaderHighlightSections">
|
<widget class="QRadioButton" name="port1Female">
|
||||||
<bool>false</bool>
|
<property name="text">
|
||||||
</attribute>
|
<string>Female</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">port1Group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<widget class="QGroupBox" name="port2Standards">
|
||||||
<item>
|
<property name="title">
|
||||||
<widget class="QPushButton" name="bMeasure">
|
<string>Port 2 Standards</string>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Measure</string>
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
</property>
|
<item>
|
||||||
<property name="icon">
|
<widget class="QRadioButton" name="port2Male">
|
||||||
<iconset theme="media-playback-start" resource="../icons.qrc">
|
<property name="text">
|
||||||
<normaloff>:/icons/play.png</normaloff>:/icons/play.png</iconset>
|
<string>Male</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<attribute name="buttonGroup">
|
||||||
</item>
|
<string notr="true">port2Group</string>
|
||||||
<item>
|
</attribute>
|
||||||
<widget class="QPushButton" name="bDelete">
|
</widget>
|
||||||
<property name="text">
|
</item>
|
||||||
<string>Delete</string>
|
<item>
|
||||||
</property>
|
<widget class="QRadioButton" name="port2Female">
|
||||||
<property name="icon">
|
<property name="text">
|
||||||
<iconset theme="edit-delete" resource="../icons.qrc">
|
<string>Female</string>
|
||||||
<normaloff>:/icons/trash.png</normaloff>:/icons/trash.png</iconset>
|
</property>
|
||||||
</property>
|
<attribute name="buttonGroup">
|
||||||
</widget>
|
<string notr="true">port2Group</string>
|
||||||
</item>
|
</attribute>
|
||||||
<item>
|
</widget>
|
||||||
<spacer name="horizontalSpacer">
|
</item>
|
||||||
<property name="orientation">
|
</layout>
|
||||||
<enum>Qt::Horizontal</enum>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
<property name="sizeHint" stdset="0">
|
<item>
|
||||||
<size>
|
<spacer name="horizontalSpacer_2">
|
||||||
<width>40</width>
|
<property name="orientation">
|
||||||
<height>20</height>
|
<enum>Qt::Horizontal</enum>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
<property name="sizeHint" stdset="0">
|
||||||
</spacer>
|
<size>
|
||||||
</item>
|
<width>40</width>
|
||||||
<item>
|
<height>20</height>
|
||||||
<widget class="QPushButton" name="bApply">
|
</size>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Apply Calibration</string>
|
</spacer>
|
||||||
</property>
|
</item>
|
||||||
<property name="icon">
|
</layout>
|
||||||
<iconset resource="../icons.qrc">
|
</item>
|
||||||
<normaloff>:/icons/ok.png</normaloff>:/icons/ok.png</iconset>
|
<item>
|
||||||
</property>
|
<widget class="QTableView" name="tableView">
|
||||||
</widget>
|
<property name="selectionBehavior">
|
||||||
</item>
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
</layout>
|
</property>
|
||||||
|
<attribute name="horizontalHeaderCascadingSectionResizes">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="horizontalHeaderStretchLastSection">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="verticalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="verticalHeaderHighlightSections">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="bMeasure">
|
||||||
|
<property name="text">
|
||||||
|
<string>Measure</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="media-playback-start" resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/play.png</normaloff>:/icons/play.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="bDelete">
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-delete" resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/trash.png</normaloff>:/icons/trash.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="bApply">
|
||||||
|
<property name="text">
|
||||||
|
<string>Apply Calibration</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/ok.png</normaloff>:/icons/ok.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
@ -99,4 +170,8 @@
|
|||||||
<include location="../icons.qrc"/>
|
<include location="../icons.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
<buttongroups>
|
||||||
|
<buttongroup name="port1Group"/>
|
||||||
|
<buttongroup name="port2Group"/>
|
||||||
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -204,6 +204,11 @@ void Calkit::edit(std::function<void (void)> done)
|
|||||||
dialog->show();
|
dialog->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Calkit::hasSeparateMaleFemaleStandards()
|
||||||
|
{
|
||||||
|
return SOLT.separate_male_female;
|
||||||
|
}
|
||||||
|
|
||||||
class Calkit::SOLT Calkit::toSOLT(double frequency, bool male_standards)
|
class Calkit::SOLT Calkit::toSOLT(double frequency, bool male_standards)
|
||||||
{
|
{
|
||||||
auto addTransmissionLine = [](complex<double> termination_reflection, double offset_impedance, double offset_delay, double offset_loss, double frequency) -> complex<double> {
|
auto addTransmissionLine = [](complex<double> termination_reflection, double offset_impedance, double offset_delay, double offset_loss, double frequency) -> complex<double> {
|
||||||
|
@ -41,6 +41,7 @@ public:
|
|||||||
void toFile(QString filename);
|
void toFile(QString filename);
|
||||||
static Calkit fromFile(QString filename);
|
static Calkit fromFile(QString filename);
|
||||||
void edit(std::function<void(void)> done = nullptr);
|
void edit(std::function<void(void)> done = nullptr);
|
||||||
|
bool hasSeparateMaleFemaleStandards();
|
||||||
SOLT toSOLT(double frequency, bool male_standards = true);
|
SOLT toSOLT(double frequency, bool male_standards = true);
|
||||||
TRL toTRL(double frequency);
|
TRL toTRL(double frequency);
|
||||||
double minFreqTRL();
|
double minFreqTRL();
|
||||||
|
@ -148,7 +148,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="mf_short">
|
<widget class="QTabWidget" name="mf_short">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab_3">
|
<widget class="QWidget" name="tab_3">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
@ -435,7 +435,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="mf_open">
|
<widget class="QTabWidget" name="mf_open">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab_5">
|
<widget class="QWidget" name="tab_5">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
@ -722,7 +722,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="mf_load">
|
<widget class="QTabWidget" name="mf_load">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab_7">
|
<widget class="QWidget" name="tab_7">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
@ -1457,12 +1457,12 @@
|
|||||||
</connections>
|
</connections>
|
||||||
<buttongroups>
|
<buttongroups>
|
||||||
<buttongroup name="OpenType"/>
|
<buttongroup name="OpenType"/>
|
||||||
<buttongroup name="TRL_Rtype"/>
|
|
||||||
<buttongroup name="LoadType"/>
|
<buttongroup name="LoadType"/>
|
||||||
<buttongroup name="ThroughType"/>
|
|
||||||
<buttongroup name="ShortType"/>
|
|
||||||
<buttongroup name="ShortType_f"/>
|
<buttongroup name="ShortType_f"/>
|
||||||
<buttongroup name="OpenType_f"/>
|
<buttongroup name="TRL_Rtype"/>
|
||||||
<buttongroup name="LoadType_f"/>
|
<buttongroup name="LoadType_f"/>
|
||||||
|
<buttongroup name="OpenType_f"/>
|
||||||
|
<buttongroup name="ShortType"/>
|
||||||
|
<buttongroup name="ThroughType"/>
|
||||||
</buttongroups>
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
Loading…
Reference in New Issue
Block a user