LibreVNA/Software/PC_Application/Calibration/calkitdialog.cpp

281 lines
11 KiB
C++
Raw Normal View History

#include "calkitdialog.h"
#include "ui_calkitdialog.h"
#include <QPushButton>
#include <QDebug>
#include <QFileDialog>
#include <fstream>
#include <touchstone.h>
#include <QtGlobal>
using namespace std;
CalkitDialog::CalkitDialog(Calkit &c, QWidget *parent) :
QDialog(parent),
ui(new Ui::CalkitDialog),
open_ok(true),
short_ok(true),
load_ok(true),
through_ok(true),
editKit(c)
{
ui->setupUi(this);
ui->OpenType->setId(ui->open_coefficients, 0);
ui->OpenType->setId(ui->open_measurement, 1);
ui->ShortType->setId(ui->short_coefficients, 0);
ui->ShortType->setId(ui->short_measurement, 1);
ui->LoadType->setId(ui->load_coefficients, 0);
ui->LoadType->setId(ui->load_measurement, 1);
ui->ThroughType->setId(ui->through_coefficients, 0);
ui->ThroughType->setId(ui->through_measurement, 1);
ui->open_touchstone->setPorts(1);
ui->short_touchstone->setPorts(1);
ui->load_touchstone->setPorts(1);
ui->through_touchstone->setPorts(2);
ui->TRL_line_max->setUnit("Hz");
ui->TRL_line_max->setPrecision(4);
ui->TRL_line_max->setPrefixes(" kMG");
ui->TRL_line_min->setUnit("Hz");
ui->TRL_line_min->setPrecision(4);
ui->TRL_line_min->setPrefixes(" kMG");
editKit.clearTouchstoneCache();
ownKit = editKit;
updateEntries();
connect(ui->TRL_line_min, &SIUnitEdit::valueChanged, [=](double newval){
2020-11-08 21:30:19 +08:00
ownKit.TRL.Line.minFreq = newval;
updateEntries();
});
connect(ui->TRL_line_max, &SIUnitEdit::valueChanged, [=](double newval){
2020-11-08 21:30:19 +08:00
ownKit.TRL.Line.maxFreq = newval;
updateEntries();
});
connect(ui->TRL_line_delay, &QLineEdit::editingFinished, [=](){
2020-11-08 21:30:19 +08:00
ownKit.TRL.Line.delay = ui->TRL_line_delay->text().toDouble();
updateEntries();
});
auto UpdateStatus = [=]() {
bool ok = true;
if(ui->open_measurement->isChecked() && !ui->open_touchstone->getStatus()) {
ok = false;
}
if(ui->short_measurement->isChecked() && !ui->short_touchstone->getStatus()) {
ok = false;
}
if(ui->load_measurement->isChecked() && !ui->load_touchstone->getStatus()) {
ok = false;
}
if(ui->through_measurement->isChecked() && !ui->through_touchstone->getStatus()) {
ok = false;
}
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ok);
ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(ok);
};
connect(ui->open_touchstone, &TouchstoneImport::statusChanged, UpdateStatus);
connect(ui->short_touchstone, &TouchstoneImport::statusChanged, UpdateStatus);
connect(ui->load_touchstone, &TouchstoneImport::statusChanged, UpdateStatus);
connect(ui->through_touchstone, &TouchstoneImport::statusChanged, UpdateStatus);
connect(ui->OpenType, qOverload<int>(&QButtonGroup::buttonClicked), [=](int) {
UpdateStatus();
});
connect(ui->ShortType, qOverload<int>(&QButtonGroup::buttonClicked), [=](int) {
UpdateStatus();
});
connect(ui->LoadType, qOverload<int>(&QButtonGroup::buttonClicked), [=](int) {
UpdateStatus();
});
connect(ui->ThroughType, qOverload<int>(&QButtonGroup::buttonClicked), [=](int) {
UpdateStatus();
});
connect(ui->buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, [this]() {
parseEntries();
editKit = ownKit;
delete this;
});
connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, [this]() {
delete this;
});
connect(ui->buttonBox->button(QDialogButtonBox::Open), &QPushButton::clicked, [=](){
auto filename = QFileDialog::getOpenFileName(this, "Open calibration kit coefficients", "", "Calibration kit files (*.calkit)", nullptr, QFileDialog::DontUseNativeDialog);
if(filename.length() > 0) {
ownKit = Calkit::fromFile(filename.toStdString());
updateEntries();
}
});
connect(ui->buttonBox->button(QDialogButtonBox::Save), &QPushButton::clicked, [=](){
auto filename = QFileDialog::getSaveFileName(this, "Save calibration kit coefficients", "", "Calibration kit files (*.calkit)", nullptr, QFileDialog::DontUseNativeDialog);
if(filename.length() > 0) {
// strip any potential file name extension and set default
auto dotPos = filename.lastIndexOf('.');
if(dotPos >= 0) {
filename.truncate(dotPos);
}
filename.append(".calkit");
parseEntries();
ownKit.toFile(filename.toStdString());
}
});
}
CalkitDialog::~CalkitDialog()
{
delete ui;
}
void CalkitDialog::parseEntries()
{
// type
2020-11-08 21:30:19 +08:00
ownKit.SOLT.Open.useMeasurements = ui->open_measurement->isChecked();
ownKit.SOLT.Short.useMeasurements = ui->short_measurement->isChecked();
ownKit.SOLT.Load.useMeasurements = ui->load_measurement->isChecked();
ownKit.SOLT.Through.useMeasurements = ui->through_measurement->isChecked();
// coefficients
2020-11-08 21:30:19 +08:00
ownKit.SOLT.Open.Z0 = ui->open_Z0->text().toDouble();
ownKit.SOLT.Open.delay = ui->open_delay->text().toDouble();
ownKit.SOLT.Open.loss = ui->open_loss->text().toDouble();
ownKit.SOLT.Open.C0 = ui->open_C0->text().toDouble();
ownKit.SOLT.Open.C1 = ui->open_C1->text().toDouble();
ownKit.SOLT.Open.C2 = ui->open_C2->text().toDouble();
ownKit.SOLT.Open.C3 = ui->open_C3->text().toDouble();
ownKit.SOLT.Short.Z0 = ui->short_Z0->text().toDouble();
ownKit.SOLT.Short.delay = ui->short_delay->text().toDouble();
ownKit.SOLT.Short.loss = ui->short_loss->text().toDouble();
ownKit.SOLT.Short.L0 = ui->short_L0->text().toDouble();
ownKit.SOLT.Short.L1 = ui->short_L1->text().toDouble();
ownKit.SOLT.Short.L2 = ui->short_L2->text().toDouble();
ownKit.SOLT.Short.L3 = ui->short_L3->text().toDouble();
ownKit.SOLT.Load.Z0 = ui->load_Z0->text().toDouble();
ownKit.SOLT.Through.Z0 = ui->through_Z0->text().toDouble();
ownKit.SOLT.Through.delay = ui->through_delay->text().toDouble();
ownKit.SOLT.Through.loss = ui->through_loss->text().toDouble();
// file
2020-11-08 21:30:19 +08:00
ownKit.SOLT.Open.file = ui->open_touchstone->getFilename();
ownKit.SOLT.Short.file = ui->short_touchstone->getFilename();
ownKit.SOLT.Load.file = ui->load_touchstone->getFilename();
ownKit.SOLT.Through.file = ui->through_touchstone->getFilename();
2020-11-08 21:30:19 +08:00
ownKit.SOLT.Open.Sparam = ui->open_touchstone->getPorts()[0];
ownKit.SOLT.Short.Sparam = ui->short_touchstone->getPorts()[0];
ownKit.SOLT.Load.Sparam = ui->load_touchstone->getPorts()[0];
ownKit.SOLT.Through.Sparam1 = ui->through_touchstone->getPorts()[0];
ownKit.SOLT.Through.Sparam2 = ui->through_touchstone->getPorts()[1];
// TRL
2020-11-08 21:30:19 +08:00
ownKit.TRL.Through.Z0 = ui->TRL_through_Z0->text().toDouble();
ownKit.TRL.Reflection.isShort = ui->TRL_R_short->isChecked();
ownKit.TRL.Line.delay = ui->TRL_line_delay->text().toDouble();
ownKit.TRL.Line.minFreq = ui->TRL_line_min->value();
ownKit.TRL.Line.maxFreq = ui->TRL_line_max->value();
ownKit.startDialogWithSOLT = ui->tabWidget->currentIndex() == 0;
}
void CalkitDialog::updateEntries()
{
// Coefficients
2020-11-08 21:30:19 +08:00
ui->open_Z0->setText(QString::number(ownKit.SOLT.Open.Z0));
ui->open_delay->setText(QString::number(ownKit.SOLT.Open.delay));
ui->open_loss->setText(QString::number(ownKit.SOLT.Open.loss));
ui->open_C0->setText(QString::number(ownKit.SOLT.Open.C0));
ui->open_C1->setText(QString::number(ownKit.SOLT.Open.C1));
ui->open_C2->setText(QString::number(ownKit.SOLT.Open.C2));
ui->open_C3->setText(QString::number(ownKit.SOLT.Open.C3));
ui->short_Z0->setText(QString::number(ownKit.SOLT.Short.Z0));
ui->short_delay->setText(QString::number(ownKit.SOLT.Short.delay));
ui->short_loss->setText(QString::number(ownKit.SOLT.Short.loss));
ui->short_L0->setText(QString::number(ownKit.SOLT.Short.L0));
ui->short_L1->setText(QString::number(ownKit.SOLT.Short.L1));
ui->short_L2->setText(QString::number(ownKit.SOLT.Short.L2));
ui->short_L3->setText(QString::number(ownKit.SOLT.Short.L3));
ui->load_Z0->setText(QString::number(ownKit.SOLT.Load.Z0));
ui->through_Z0->setText(QString::number(ownKit.SOLT.Through.Z0));
ui->through_delay->setText(QString::number(ownKit.SOLT.Through.delay));
ui->through_loss->setText(QString::number(ownKit.SOLT.Through.loss));
// Measurements
2020-11-08 21:30:19 +08:00
ui->open_touchstone->setFile(ownKit.SOLT.Open.file);
ui->open_touchstone->selectPort(0, ownKit.SOLT.Open.Sparam);
2020-11-08 21:30:19 +08:00
ui->short_touchstone->setFile(ownKit.SOLT.Short.file);
ui->short_touchstone->selectPort(0, ownKit.SOLT.Short.Sparam);
2020-11-08 21:30:19 +08:00
ui->load_touchstone->setFile(ownKit.SOLT.Load.file);
ui->load_touchstone->selectPort(0, ownKit.SOLT.Load.Sparam);
2020-11-08 21:30:19 +08:00
ui->through_touchstone->setFile(ownKit.SOLT.Through.file);
ui->through_touchstone->selectPort(0, ownKit.SOLT.Through.Sparam1);
ui->through_touchstone->selectPort(1, ownKit.SOLT.Through.Sparam2);
// Type
2020-11-08 21:30:19 +08:00
if (ownKit.SOLT.Open.useMeasurements) {
ui->open_measurement->click();
} else {
ui->open_coefficients->click();
}
2020-11-08 21:30:19 +08:00
if (ownKit.SOLT.Short.useMeasurements) {
ui->short_measurement->click();
} else {
ui->short_coefficients->click();
}
2020-11-08 21:30:19 +08:00
if (ownKit.SOLT.Load.useMeasurements) {
ui->load_measurement->click();
} else {
ui->load_coefficients->click();
}
2020-11-08 21:30:19 +08:00
if (ownKit.SOLT.Through.useMeasurements) {
ui->through_measurement->click();
} else {
ui->through_coefficients->click();
}
// TRL
2020-11-08 21:30:19 +08:00
ui->TRL_through_Z0->setText(QString::number(ownKit.TRL.Through.Z0));
if(ownKit.TRL.Reflection.isShort) {
ui->TRL_R_short->setChecked(true);
} else {
ui->TRL_R_open->setChecked(true);
}
2020-11-08 21:30:19 +08:00
ui->TRL_line_delay->setText(QString::number(ownKit.TRL.Line.delay));
ui->TRL_line_min->setValueQuiet(ownKit.TRL.Line.minFreq);
ui->TRL_line_max->setValueQuiet(ownKit.TRL.Line.maxFreq);
// Check if line length is appropriate for frequencies
2020-11-08 21:30:19 +08:00
auto minDelay = 20.0/(ownKit.TRL.Line.minFreq * 360.0) * 1e12;
auto maxDelay = 160.0/(ownKit.TRL.Line.maxFreq * 360.0) * 1e12;
if(ownKit.TRL.Line.delay < minDelay) {
ui->TRL_line_warning->setText("Line too short, minimum required delay is "+QString::number(minDelay, 'g', 3) + "ps");
2020-11-08 21:30:19 +08:00
} else if(ownKit.TRL.Line.delay > maxDelay) {
ui->TRL_line_warning->setText("Line too long, maximum allowed delay is "+QString::number(maxDelay, 'g', 3) + "ps");
} else {
ui->TRL_line_warning->clear();
}
2020-11-08 21:30:19 +08:00
if (ownKit.startDialogWithSOLT) {
ui->tabWidget->setCurrentIndex(0);
} else {
ui->tabWidget->setCurrentIndex(1);
}
}