diff --git a/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.cpp b/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.cpp index 18d06c1..8cdb025 100644 --- a/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.cpp @@ -6,6 +6,7 @@ #include "Util/util.h" #include "LibreCAL/librecaldialog.h" #include "preferences.h" +#include "Traces/sparamtraceselectordialog.h" #include "Tools/Eigen/Dense" @@ -408,7 +409,7 @@ void Calibration::correctTraces(std::map traceSet) } } -void Calibration::edit() +void Calibration::edit(TraceModel *traceModel) { auto d = new QDialog(); d->setAttribute(Qt::WA_DeleteOnClose); @@ -510,6 +511,10 @@ void Calibration::edit() ui->bDelete->setEnabled(ui->table->currentRow() >= 0); ui->bMoveUp->setEnabled(ui->table->currentRow() >= 1); ui->bMoveDown->setEnabled(ui->table->currentRow() >= 0 && ui->table->currentRow() < ui->table->rowCount() - 1); + auto selected = ui->table->selectionModel()->selectedRows(); + ui->measure->setEnabled(selected.size() > 0); + ui->selectMeasurement->setEnabled(traceModel && selected.size() == 1); + ui->clearMeasurement->setEnabled(selected.size() > 0); }; auto updateMeasurementTable = [=](){ @@ -619,6 +624,35 @@ void Calibration::edit() emit startMeasurements(m); }); + connect(ui->selectMeasurement, &QPushButton::clicked, [=](){ + auto selected = ui->table->selectionModel()->selectedRows(); + if(selected.size() != 1) { + InformationBox::ShowError("Unable to select measurement", "Exactly one measurement must be selected"); + return; + } + // figure out which S parameters we need + auto meas = measurements[selected[0].row()]; + auto ports = meas->getPorts(); + if(ports.size() == 0) { + InformationBox::ShowError("Unable to select measurement", "Selecting measurements for this type of calibration measurement is not supported"); + return; + } + auto selector = new SParamTraceSelectorDialog(*traceModel, ports); + connect(selector, &SParamTraceSelectorDialog::tracesSelected, d, [=](std::vector traceMeasurements){ + clearMeasurements({meas}); + for(const auto &tm : traceMeasurements) { + addMeasurements({meas}, tm); + } + updateMeasurementTable(); + updateCalibrationList(); + }); + selector->show(); + }); + if(!traceModel) { + // can not select a measurement if no trace model is supplied + ui->selectMeasurement->setEnabled(false); + } + connect(this, &Calibration::measurementsUpdated, d, [=](){ updateMeasurementTable(); updateCalibrationList(); @@ -665,7 +699,7 @@ void Calibration::edit() }); }); - QObject::connect(ui->table, &QTableWidget::currentCellChanged, updateTableEditButtons); + QObject::connect(ui->table, &QTableWidget::itemSelectionChanged, updateTableEditButtons); auto addMenu = new QMenu(); for(auto t : CalibrationMeasurement::Base::availableTypes()) { @@ -802,6 +836,7 @@ Calibration::Point Calibration::computeSOLT(double f) auto deltaS = Sideal.get(1,1)*Sideal.get(2,2) - Sideal.get(2,1) * Sideal.get(1,2); point.L[i][j] = ((S11 - point.D[i])*(1.0 - point.S[i] * Sideal.get(1,1))-Sideal.get(1,1)*point.R[i]) / ((S11 - point.D[i])*(Sideal.get(2,2)-point.S[i]*deltaS)-deltaS*point.R[i]); + point.L[i][j] = 0.0; point.T[i][j] = (S21 - isolation)*(1.0 - point.S[i]*Sideal.get(1,1) - point.L[i][j]*Sideal.get(2,2) + point.S[i]*point.L[i][j]*deltaS) / Sideal.get(2,1); point.I[i][j] = isolation; } diff --git a/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.h b/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.h index 9efe3c1..49a1b17 100644 --- a/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.h +++ b/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.h @@ -46,7 +46,7 @@ public: void correctTraces(std::map traceSet); // Starts the calibration edit dialog, allowing the user to make/delete measurements - void edit(); + void edit(TraceModel *traceModel = nullptr); Calkit& getKit(); diff --git a/Software/PC_Application/LibreVNA-GUI/Calibration/calibrationdialogui.ui b/Software/PC_Application/LibreVNA-GUI/Calibration/calibrationdialogui.ui index 00cc5ba..e3ae93e 100644 --- a/Software/PC_Application/LibreVNA-GUI/Calibration/calibrationdialogui.ui +++ b/Software/PC_Application/LibreVNA-GUI/Calibration/calibrationdialogui.ui @@ -48,7 +48,7 @@ - QAbstractItemView::SelectRows + QAbstractItemView::SelectionBehavior::SelectRows true @@ -148,6 +148,14 @@ + + + + Select +Measurement + + + @@ -185,7 +193,7 @@ Kit - Qt::Vertical + Qt::Orientation::Vertical @@ -287,7 +295,7 @@ Kit - Qt::Vertical + Qt::Orientation::Vertical diff --git a/Software/PC_Application/LibreVNA-GUI/Calibration/calibrationmeasurement.h b/Software/PC_Application/LibreVNA-GUI/Calibration/calibrationmeasurement.h index 8161e8b..51fbf3d 100644 --- a/Software/PC_Application/LibreVNA-GUI/Calibration/calibrationmeasurement.h +++ b/Software/PC_Application/LibreVNA-GUI/Calibration/calibrationmeasurement.h @@ -61,6 +61,8 @@ public: virtual nlohmann::json toJSON() override; virtual void fromJSON(nlohmann::json j) override; + virtual std::vector getPorts() = 0; + static bool canMeasureSimultaneously(std::set measurements); QDateTime getTimestamp() const; @@ -102,6 +104,8 @@ public: virtual nlohmann::json toJSON() override; virtual void fromJSON(nlohmann::json j) override; + virtual std::vector getPorts() override {return {port};} + class Point { public: double frequency; @@ -222,6 +226,8 @@ public: virtual nlohmann::json toJSON() override; virtual void fromJSON(nlohmann::json j) override; + virtual std::vector getPorts() override {return {port1, port2};} + class Point { public: double frequency; @@ -298,6 +304,8 @@ public: virtual nlohmann::json toJSON() override; virtual void fromJSON(nlohmann::json j) override; + virtual std::vector getPorts() override {return {};} + class Point { public: double frequency; diff --git a/Software/PC_Application/LibreVNA-GUI/LibreVNA-GUI.pro b/Software/PC_Application/LibreVNA-GUI/LibreVNA-GUI.pro index 0337498..c34f55f 100644 --- a/Software/PC_Application/LibreVNA-GUI/LibreVNA-GUI.pro +++ b/Software/PC_Application/LibreVNA-GUI/LibreVNA-GUI.pro @@ -116,6 +116,7 @@ HEADERS += \ Traces/eyediagramplot.h \ Traces/fftcomplex.h \ Traces/sparamtraceselector.h \ + Traces/sparamtraceselectordialog.h \ Traces/trace.h \ Traces/traceaxis.h \ Traces/tracecsvexport.h \ @@ -271,6 +272,7 @@ SOURCES += \ Traces/eyediagramplot.cpp \ Traces/fftcomplex.cpp \ Traces/sparamtraceselector.cpp \ + Traces/sparamtraceselectordialog.cpp \ Traces/trace.cpp \ Traces/traceaxis.cpp \ Traces/tracecsvexport.cpp \ @@ -389,6 +391,7 @@ FORMS += \ Traces/eyediagrameditdialog.ui \ Traces/smithchartdialog.ui \ Traces/polarchartdialog.ui \ + Traces/sparamtraceselectordialog.ui \ Traces/tracecsvexport.ui \ Traces/traceeditdialog.ui \ Traces/traceimportdialog.ui \ diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselector.cpp b/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselector.cpp index 572d6ff..50164f6 100644 --- a/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselector.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselector.cpp @@ -13,7 +13,8 @@ SparamTraceSelector::SparamTraceSelector(const TraceModel &model, std::vectorcurrentIndex() == 0 && points > 0) { if(!empty_allowed) { + valid = false; emit selectionValid(false); } // Check if all trace selections are set for none @@ -161,7 +163,8 @@ void SparamTraceSelector::traceSelectionChanged(QComboBox *cb) } if(empty_allowed) { // always valid as soon as at least one trace is selected - emit selectionValid(points > 0); + valid = points > 0; + emit selectionValid(valid); } else { // actually need to check valid = true; diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselector.h b/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselector.h index dd6a559..d056a9f 100644 --- a/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselector.h +++ b/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselector.h @@ -16,7 +16,7 @@ public: SparamTraceSelector(const TraceModel &model, std::vector used_ports, bool empty_allowed = false, unsigned int editablePorts = 0); SparamTraceSelector(const TraceModel &model, std::set used_ports, bool empty_allowed = false, unsigned int editablePorts = 0); - bool isValid(); + bool isValid() {return valid;} std::map getTraces(); unsigned int getPoints() { return points;} diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselectordialog.cpp b/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselectordialog.cpp new file mode 100644 index 0000000..647b5d6 --- /dev/null +++ b/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselectordialog.cpp @@ -0,0 +1,36 @@ +#include "sparamtraceselectordialog.h" +#include "ui_sparamtraceselectordialog.h" + +#include "sparamtraceselector.h" +#include + +SParamTraceSelectorDialog::SParamTraceSelectorDialog(const TraceModel &model, std::vector used_ports, bool empty_allowed) + : QDialog(nullptr) + , ui(new Ui::SParamTraceSelectorDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + auto selector = new SparamTraceSelector(model, used_ports, empty_allowed); + ui->verticalLayout->replaceWidget(ui->placeholder, selector); + + auto okButton = ui->buttonBox->button(QDialogButtonBox::StandardButton::Ok); + connect(selector, &SparamTraceSelector::selectionValid, okButton, &QPushButton::setEnabled); + okButton->setEnabled(selector->isValid()); + + connect(okButton, &QPushButton::clicked, [=](){ + auto traces = selector->getTraces(); + if(traces.size() == 0) { + // should not happen + reject(); + } + emit tracesSelected(Trace::assembleDatapoints(traces)); + accept(); + }); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &SParamTraceSelectorDialog::reject); +} + +SParamTraceSelectorDialog::~SParamTraceSelectorDialog() +{ + delete ui; +} diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselectordialog.h b/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselectordialog.h new file mode 100644 index 0000000..e832627 --- /dev/null +++ b/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselectordialog.h @@ -0,0 +1,27 @@ +#ifndef SPARAMTRACESELECTORDIALOG_H +#define SPARAMTRACESELECTORDIALOG_H + +#include + +#include "tracemodel.h" + +namespace Ui { +class SParamTraceSelectorDialog; +} + +class SParamTraceSelectorDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SParamTraceSelectorDialog(const TraceModel &model, std::vector used_ports, bool empty_allowed = false); + ~SParamTraceSelectorDialog(); + +signals: + void tracesSelected(std::vector traceMeasurements); + +private: + Ui::SParamTraceSelectorDialog *ui; +}; + +#endif // SPARAMTRACESELECTORDIALOG_H diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselectordialog.ui b/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselectordialog.ui new file mode 100644 index 0000000..751f0c8 --- /dev/null +++ b/Software/PC_Application/LibreVNA-GUI/Traces/sparamtraceselectordialog.ui @@ -0,0 +1,34 @@ + + + SParamTraceSelectorDialog + + + Qt::WindowModality::ApplicationModal + + + + 0 + 0 + 494 + 222 + + + + S-Paramter Trace Selector Dialog + + + + + + + + + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + + + + + + + + diff --git a/Software/PC_Application/LibreVNA-GUI/VNA/vna.cpp b/Software/PC_Application/LibreVNA-GUI/VNA/vna.cpp index 75fb076..e418b30 100644 --- a/Software/PC_Application/LibreVNA-GUI/VNA/vna.cpp +++ b/Software/PC_Application/LibreVNA-GUI/VNA/vna.cpp @@ -110,7 +110,7 @@ VNA::VNA(AppWindow *window, QString name) auto calData = calMenu->addAction("Calibration Measurements"); connect(calData, &QAction::triggered, [=](){ - cal.edit(); + cal.edit(&traceModel); }); auto calEditKit = calMenu->addAction("Edit Calibration Kit"); @@ -1375,7 +1375,7 @@ void VNA::ApplyCalibration(Calibration::CalType type) // Not all required traces available InformationBox::ShowMessageBlocking("Missing calibration measurements", "Not all calibration measurements for this type of calibration have been taken. The calibration can be enabled after the missing measurements have been acquired."); DisableCalibration(); - cal.edit(); + cal.edit(&traceModel); } else { // Not all required traces available InformationBox::ShowMessageBlocking("Missing calibration measurements", "Not all calibration measurements for this type of calibration have been taken. Please switch to frequency sweep to take these measurements."); diff --git a/Software/PC_Application/LibreVNA-Test/LibreVNA-Test.pro b/Software/PC_Application/LibreVNA-Test/LibreVNA-Test.pro index 56cd18a..d16488f 100644 --- a/Software/PC_Application/LibreVNA-Test/LibreVNA-Test.pro +++ b/Software/PC_Application/LibreVNA-Test/LibreVNA-Test.pro @@ -110,6 +110,7 @@ SOURCES += \ ../LibreVNA-GUI/Traces/eyediagramplot.cpp \ ../LibreVNA-GUI/Traces/fftcomplex.cpp \ ../LibreVNA-GUI/Traces/sparamtraceselector.cpp \ + ../LibreVNA-GUI/Traces/sparamtraceselectordialog.cpp \ ../LibreVNA-GUI/Traces/trace.cpp \ ../LibreVNA-GUI/Traces/traceaxis.cpp \ ../LibreVNA-GUI/Traces/tracecsvexport.cpp \ @@ -310,6 +311,7 @@ HEADERS += \ ../LibreVNA-GUI/Traces/eyediagramplot.h \ ../LibreVNA-GUI/Traces/fftcomplex.h \ ../LibreVNA-GUI/Traces/sparamtraceselector.h \ + ../LibreVNA-GUI/Traces/sparamtraceselectordialog.h \ ../LibreVNA-GUI/Traces/trace.h \ ../LibreVNA-GUI/Traces/traceaxis.h \ ../LibreVNA-GUI/Traces/tracecsvexport.h \ @@ -425,6 +427,7 @@ FORMS += \ ../LibreVNA-GUI/Traces/eyediagrameditdialog.ui \ ../LibreVNA-GUI/Traces/polarchartdialog.ui \ ../LibreVNA-GUI/Traces/smithchartdialog.ui \ + ../LibreVNA-GUI/Traces/sparamtraceselectordialog.ui \ ../LibreVNA-GUI/Traces/tracecsvexport.ui \ ../LibreVNA-GUI/Traces/traceeditdialog.ui \ ../LibreVNA-GUI/Traces/traceimportdialog.ui \