From 0d6e844defa80aabdce3b7b549de17869d6a9eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20K=C3=A4berich?= Date: Tue, 10 Nov 2020 19:16:16 +0100 Subject: [PATCH] More intuitive handling of calibration measurements - Allow saving of calibration only if a calibration is active (no more calibration files that "don't do anything" when they are opened) - Delete old measurements when loading a new calibration file - Update calibration when a measurement is updated (no need to disable and enable again) - Disable calibration when a required measurement is deleted --- Software/PC_Application/Application.pro | 2 + .../Calibration/calibration.cpp | 31 ++++++++----- .../Calibration/calibrationtracedialog.cpp | 30 ++++++------- .../Calibration/calibrationtracedialog.h | 7 +-- .../Calibration/calibrationtracedialog.ui | 28 ++---------- .../PC_Application/Calibration/calkit.cpp | 24 +++++------ Software/PC_Application/Calibration/calkit.h | 4 +- .../Calibration/calkitdialog.cpp | 10 +---- .../CustomWidgets/informationbox.cpp | 43 +++++++++++++++++++ .../CustomWidgets/informationbox.h | 18 ++++++++ Software/PC_Application/VNA/vna.cpp | 39 ++++++++++++++--- Software/PC_Application/VNA/vna.h | 1 + 12 files changed, 149 insertions(+), 88 deletions(-) create mode 100644 Software/PC_Application/CustomWidgets/informationbox.cpp create mode 100644 Software/PC_Application/CustomWidgets/informationbox.h diff --git a/Software/PC_Application/Application.pro b/Software/PC_Application/Application.pro index cb73783..abe26bc 100644 --- a/Software/PC_Application/Application.pro +++ b/Software/PC_Application/Application.pro @@ -7,6 +7,7 @@ HEADERS += \ Calibration/json.hpp \ Calibration/measurementmodel.h \ CustomWidgets/colorpickerbutton.h \ + CustomWidgets/informationbox.h \ CustomWidgets/siunitedit.h \ CustomWidgets/tilewidget.h \ CustomWidgets/toggleswitch.h \ @@ -53,6 +54,7 @@ SOURCES += \ Calibration/calkitdialog.cpp \ Calibration/measurementmodel.cpp \ CustomWidgets/colorpickerbutton.cpp \ + CustomWidgets/informationbox.cpp \ CustomWidgets/qwtplotpiecewisecurve.cpp \ CustomWidgets/siunitedit.cpp \ CustomWidgets/tilewidget.cpp \ diff --git a/Software/PC_Application/Calibration/calibration.cpp b/Software/PC_Application/Calibration/calibration.cpp index 5849d77..c4f87a5 100644 --- a/Software/PC_Application/Calibration/calibration.cpp +++ b/Software/PC_Application/Calibration/calibration.cpp @@ -24,7 +24,7 @@ Calibration::Calibration() void Calibration::clearMeasurements() { for(auto m : measurements) { - m.second.datapoints.clear(); + clearMeasurement(m.first); } } @@ -42,11 +42,19 @@ void Calibration::addMeasurement(Calibration::Measurement type, Protocol::Datapo bool Calibration::calculationPossible(Calibration::Type type) { + if(type == Type::None) { + // always possible to reset to None + return true; + } return SanityCheckSamples(Measurements(type, false)); } #include bool Calibration::constructErrorTerms(Calibration::Type type) { + if(type == Type::None) { + resetErrorTerms(); + return true; + } if(!calculationPossible(type)) { return false; } @@ -602,6 +610,10 @@ bool Calibration::openFromFile(QString filename) } } + // reset all data before loading new calibration + clearMeasurements(); + resetErrorTerms(); + // attempt to load associated calibration kit first (needs to be available when performing calibration) auto calkit_file = filename; auto dotPos = calkit_file.lastIndexOf('.'); @@ -610,7 +622,7 @@ bool Calibration::openFromFile(QString filename) } calkit_file.append(".calkit"); try { - kit = Calkit::fromFile(calkit_file.toStdString()); + kit = Calkit::fromFile(calkit_file); } catch (runtime_error e) { QMessageBox::warning(nullptr, "Missing calibration kit", "The calibration kit file associated with the selected calibration could not be parsed. The calibration might not be accurate. (" + QString(e.what()) + ")"); } @@ -636,20 +648,17 @@ bool Calibration::saveToFile(QString filename) return false; } } - // strip any potential file name extension and set default - auto dotPos = filename.lastIndexOf('.'); - if(dotPos >= 0) { - filename.truncate(dotPos); + + if(filename.endsWith(".cal")) { + filename.chop(4); } - auto calibration_file = filename; - calibration_file.append(".cal"); + auto calibration_file = filename + ".cal"; ofstream file; file.open(calibration_file.toStdString()); file << *this; - auto calkit_file = filename; - calkit_file.append(".calkit"); - kit.toFile(calkit_file.toStdString()); + auto calkit_file = filename + ".calkit"; + kit.toFile(calkit_file); return true; } diff --git a/Software/PC_Application/Calibration/calibrationtracedialog.cpp b/Software/PC_Application/Calibration/calibrationtracedialog.cpp index ed8e944..d6717b0 100644 --- a/Software/PC_Application/Calibration/calibrationtracedialog.cpp +++ b/Software/PC_Application/Calibration/calibrationtracedialog.cpp @@ -21,7 +21,7 @@ CalibrationTraceDialog::CalibrationTraceDialog(Calibration *cal, Calibration::Ty ui->tableView->setColumnWidth(1, 350); ui->tableView->setColumnWidth(2, 320); ui->tableView->setColumnWidth(3, 160); - UpdateApplyButton(); + UpdateCalibrationStatus(); } CalibrationTraceDialog::~CalibrationTraceDialog() @@ -32,11 +32,19 @@ CalibrationTraceDialog::~CalibrationTraceDialog() void CalibrationTraceDialog::measurementComplete(Calibration::Measurement m) { model->measurementUpdated(m); - UpdateApplyButton(); + UpdateCalibrationStatus(); } -void CalibrationTraceDialog::UpdateApplyButton() +void CalibrationTraceDialog::UpdateCalibrationStatus() { + if(!cal->calculationPossible(cal->getType())) { + // some trace for the current calibration was deleted + cal->resetErrorTerms(); + emit calibrationInvalidated(); + } else { + // update error terms as a measurement might have changed + cal->constructErrorTerms(cal->getType()); + } ui->bApply->setEnabled(cal->calculationPossible(requestedType)); } @@ -45,7 +53,7 @@ void CalibrationTraceDialog::on_bDelete_clicked() auto measurement = measurements[ui->tableView->currentIndex().row()]; cal->clearMeasurement(measurement); model->measurementUpdated(measurement); - UpdateApplyButton(); + UpdateCalibrationStatus(); } void CalibrationTraceDialog::on_bMeasure_clicked() @@ -59,17 +67,3 @@ void CalibrationTraceDialog::on_bApply_clicked() emit applyCalibration(requestedType); accept(); } - -void CalibrationTraceDialog::on_bOpen_clicked() -{ - cal->openFromFile(); - UpdateApplyButton(); - if(cal->getType() != Calibration::Type::None) { - emit applyCalibration(cal->getType()); - } -} - -void CalibrationTraceDialog::on_bSave_clicked() -{ - cal->saveToFile(); -} diff --git a/Software/PC_Application/Calibration/calibrationtracedialog.h b/Software/PC_Application/Calibration/calibrationtracedialog.h index b581c00..2d8546d 100644 --- a/Software/PC_Application/Calibration/calibrationtracedialog.h +++ b/Software/PC_Application/Calibration/calibrationtracedialog.h @@ -22,18 +22,15 @@ public slots: signals: void triggerMeasurement(Calibration::Measurement m); void applyCalibration(Calibration::Type type); + void calibrationInvalidated(); private slots: void on_bDelete_clicked(); void on_bMeasure_clicked(); void on_bApply_clicked(); - void on_bOpen_clicked(); - - void on_bSave_clicked(); - private: - void UpdateApplyButton(); + void UpdateCalibrationStatus(); Ui::CalibrationTraceDialog *ui; Calibration *cal; Calibration::Type requestedType; diff --git a/Software/PC_Application/Calibration/calibrationtracedialog.ui b/Software/PC_Application/Calibration/calibrationtracedialog.ui index 32597b8..33c30c5 100644 --- a/Software/PC_Application/Calibration/calibrationtracedialog.ui +++ b/Software/PC_Application/Calibration/calibrationtracedialog.ui @@ -6,12 +6,12 @@ 0 0 - 1066 - 396 + 1079 + 578 - Calibration Traces + Calibration Measurements true @@ -65,28 +65,6 @@ - - - - Open - - - - :/icons/open.png:/icons/open.png - - - - - - - Save - - - - :/icons/save.png:/icons/save.png - - - diff --git a/Software/PC_Application/Calibration/calkit.cpp b/Software/PC_Application/Calibration/calkit.cpp index 82a2917..48055d6 100644 --- a/Software/PC_Application/Calibration/calkit.cpp +++ b/Software/PC_Application/Calibration/calkit.cpp @@ -26,9 +26,12 @@ Calkit::Calkit() #include -void Calkit::toFile(std::string filename) -{ - TransformPathsToRelative(QString::fromStdString(filename)); +void Calkit::toFile(QString filename) +{ + if(!filename.endsWith(".calkit")) { + filename.append(".calkit"); + } + TransformPathsToRelative(filename); json j; for(auto e : json_descr) { @@ -39,7 +42,6 @@ void Calkit::toFile(std::string filename) } // json library does not now about QVariant, handle used cases auto val = e.var.value(); - qDebug() << val << endl; switch(static_cast(val.type())) { case QMetaType::Double: *json_entry = val.toDouble(); break; case QMetaType::Int: *json_entry = val.toInt(); break; @@ -50,11 +52,11 @@ void Calkit::toFile(std::string filename) } } ofstream file; - file.open(filename); + file.open(filename.toStdString()); file << setw(4) << j << endl; file.close(); - TransformPathsToAbsolute(QString::fromStdString(filename)); + TransformPathsToAbsolute(filename); } static QString readLine(ifstream &file) { @@ -63,11 +65,11 @@ static QString readLine(ifstream &file) { return QString::fromStdString(line).simplified(); } -Calkit Calkit::fromFile(std::string filename) +Calkit Calkit::fromFile(QString filename) { auto c = Calkit(); ifstream file; - file.open(filename); + file.open(filename.toStdString()); if(!file.is_open()) { throw runtime_error("Unable to open file"); } @@ -101,9 +103,7 @@ Calkit Calkit::fromFile(std::string filename) case QMetaType::Bool: e.var.setValue((*json_entry).get()); break; case QMetaType::QString: { auto s = QString::fromStdString((*json_entry).get()); - qDebug() << s; e.var.setValue(s); - qDebug() << e.var.value(); } break; @@ -162,7 +162,7 @@ Calkit Calkit::fromFile(std::string filename) auto msg = new QMessageBox(); msg->setWindowTitle("Loading calkit file"); - msg->setText("The file \"" + QString::fromStdString(filename) + "\" is stored in a deprecated" + msg->setText("The file \"" + filename + "\" is stored in a deprecated" " calibration kit format. Future versions of this application might not support" " it anymore. Please save the calibration kit to update to the new format"); msg->setStandardButtons(QMessageBox::Ok); @@ -170,7 +170,7 @@ Calkit Calkit::fromFile(std::string filename) } file.close(); - c.TransformPathsToAbsolute(QString::fromStdString(filename)); + c.TransformPathsToAbsolute(filename); // set default values for non-editable items (for now) c.TRL.Through.Z0 = 50.0; diff --git a/Software/PC_Application/Calibration/calkit.h b/Software/PC_Application/Calibration/calkit.h index 4d080bb..736d77c 100644 --- a/Software/PC_Application/Calibration/calkit.h +++ b/Software/PC_Application/Calibration/calkit.h @@ -34,8 +34,8 @@ public: std::complex ThroughS11, ThroughS12, ThroughS21, ThroughS22; }; - void toFile(std::string filename); - static Calkit fromFile(std::string filename); + void toFile(QString filename); + static Calkit fromFile(QString filename); void edit(); SOLT toSOLT(double frequency); TRL toTRL(double frequency); diff --git a/Software/PC_Application/Calibration/calkitdialog.cpp b/Software/PC_Application/Calibration/calkitdialog.cpp index d0f964a..70b6a64 100644 --- a/Software/PC_Application/Calibration/calkitdialog.cpp +++ b/Software/PC_Application/Calibration/calkitdialog.cpp @@ -119,7 +119,7 @@ CalkitDialog::CalkitDialog(Calkit &c, QWidget *parent) : 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()); + ownKit = Calkit::fromFile(filename); updateEntries(); } }); @@ -127,14 +127,8 @@ CalkitDialog::CalkitDialog(Calkit &c, QWidget *parent) : 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()); + ownKit.toFile(filename); } }); } diff --git a/Software/PC_Application/CustomWidgets/informationbox.cpp b/Software/PC_Application/CustomWidgets/informationbox.cpp new file mode 100644 index 0000000..0e4e2da --- /dev/null +++ b/Software/PC_Application/CustomWidgets/informationbox.cpp @@ -0,0 +1,43 @@ +#include "informationbox.h" +#include +#include +#include + +void InformationBox::ShowMessage(QString title, QString message, QWidget *parent) +{ + // check if the user still wants to see this message + auto hash = qHash(message); + + QSettings s; + if(!s.contains(hashToSettingsKey(hash))) { + auto box = new InformationBox(title, message, hash, parent); + box->exec(); + } +} + +InformationBox::InformationBox(QString title, QString message, unsigned int hash, QWidget *parent) + : QMessageBox(parent), + hash(hash) +{ + setWindowTitle(title); + setText(message); + setAttribute(Qt::WA_DeleteOnClose, true); + setIcon(QMessageBox::Information); + + auto cb = new QCheckBox("Do not show this message again"); + setCheckBox(cb); +} + +InformationBox::~InformationBox() +{ + auto cb = checkBox(); + if(cb->isChecked()) { + QSettings s; + s.setValue(hashToSettingsKey(hash), true); + } +} + +QString InformationBox::hashToSettingsKey(unsigned int hash) +{ + return QString("DoNotShowDialog/") + QString::number(hash); +} diff --git a/Software/PC_Application/CustomWidgets/informationbox.h b/Software/PC_Application/CustomWidgets/informationbox.h new file mode 100644 index 0000000..262deed --- /dev/null +++ b/Software/PC_Application/CustomWidgets/informationbox.h @@ -0,0 +1,18 @@ +#ifndef INFORMATIONBOX_H +#define INFORMATIONBOX_H + +#include + +class InformationBox : public QMessageBox +{ + Q_OBJECT +public: + static void ShowMessage(QString title, QString message, QWidget *parent = nullptr); +private: + InformationBox(QString title, QString message, unsigned int hash, QWidget *parent); + ~InformationBox(); + static QString hashToSettingsKey(unsigned int hash); + unsigned int hash; +}; + +#endif // INFORMATIONBOX_H diff --git a/Software/PC_Application/VNA/vna.cpp b/Software/PC_Application/VNA/vna.cpp index 3bd9b74..a1cf3dc 100644 --- a/Software/PC_Application/VNA/vna.cpp +++ b/Software/PC_Application/VNA/vna.cpp @@ -41,6 +41,8 @@ #include #include #include +#include +#include "CustomWidgets/informationbox.h" VNA::VNA(AppWindow *window) : Mode(window, "Vector Network Analyzer"), @@ -89,11 +91,29 @@ VNA::VNA(AppWindow *window) auto calMenu = new QMenu("Calibration", window); window->menuBar()->insertMenu(window->getUi()->menuWindow->menuAction(), calMenu); actions.insert(calMenu->menuAction()); + auto calLoad = calMenu->addAction("Load"); + saveCal = calMenu->addAction("Save"); + calMenu->addSeparator(); + saveCal->setEnabled(false); + + connect(calLoad, &QAction::triggered, [=](){ + cal.openFromFile(); + if(cal.getType() == Calibration::Type::None) { + DisableCalibration(); + } else { + ApplyCalibration(cal.getType()); + } + }); + + connect(saveCal, &QAction::triggered, [=](){ + cal.saveToFile(); + }); + auto calDisable = calMenu->addAction("Disabled"); calDisable->setCheckable(true); calDisable->setChecked(true); calMenu->addSeparator(); - auto calData = calMenu->addAction("Calibration Data"); + auto calData = calMenu->addAction("Calibration Measurements"); connect(calData, &QAction::triggered, [=](){ StartCalibrationDialog(); }); @@ -290,6 +310,7 @@ VNA::VNA(AppWindow *window) cbType->blockSignals(false); cbEnableCal->blockSignals(false); calImport->setEnabled(false); + saveCal->setEnabled(false); }); connect(calDisable, &QAction::triggered, this, &VNA::DisableCalibration); connect(this, &VNA::CalibrationApplied, [=](Calibration::Type applied){ @@ -305,6 +326,7 @@ VNA::VNA(AppWindow *window) cbType->blockSignals(false); cbEnableCal->blockSignals(false); calImport->setEnabled(true); + saveCal->setEnabled(true); }); tb_cal->addWidget(cbType); @@ -383,9 +405,10 @@ void VNA::initializeDevice() auto filename = s.value(key).toString(); qDebug() << "Attempting to load default calibration file \"" << filename << "\""; if(QFile::exists(filename)) { - cal.openFromFile(filename); - ApplyCalibration(cal.getType()); - portExtension.setCalkit(&cal.getCalibrationKit()); + if(cal.openFromFile(filename)) { + ApplyCalibration(cal.getType()); + portExtension.setCalkit(&cal.getCalibrationKit()); + } } removeDefaultCal->setEnabled(true); } else { @@ -594,7 +617,6 @@ void VNA::DisableCalibration(bool force) if(calValid || force) { calValid = false; emit CalibrationDisabled(); - average.reset(settings.points); } } @@ -604,7 +626,6 @@ void VNA::ApplyCalibration(Calibration::Type type) try { if(cal.constructErrorTerms(type)) { calValid = true; - average.reset(settings.points); emit CalibrationApplied(type); } } catch (runtime_error e) { @@ -613,7 +634,7 @@ void VNA::ApplyCalibration(Calibration::Type type) } } else { // Not all required traces available - QMessageBox::information(window, "Missing calibration traces", "Not all calibration traces for this type of calibration have been measured. The calibration can be enabled after the missing traces have been acquired."); + InformationBox::ShowMessage("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.", window); DisableCalibration(true); StartCalibrationDialog(type); } @@ -708,5 +729,9 @@ void VNA::StartCalibrationDialog(Calibration::Type type) connect(traceDialog, &CalibrationTraceDialog::triggerMeasurement, this, &VNA::StartCalibrationMeasurement); connect(traceDialog, &CalibrationTraceDialog::applyCalibration, this, &VNA::ApplyCalibration); connect(this, &VNA::CalibrationMeasurementComplete, traceDialog, &CalibrationTraceDialog::measurementComplete); + connect(traceDialog, &CalibrationTraceDialog::calibrationInvalidated, [=](){ + DisableCalibration(true); + InformationBox::ShowMessage("Calibration disabled", "The currently active calibration is no longer supported by the available measurements and was disabled."); + }); traceDialog->show(); } diff --git a/Software/PC_Application/VNA/vna.h b/Software/PC_Application/VNA/vna.h index e92e376..e78d755 100644 --- a/Software/PC_Application/VNA/vna.h +++ b/Software/PC_Application/VNA/vna.h @@ -69,6 +69,7 @@ private: QMenu *defaultCalMenu; QAction *assignDefaultCal, *removeDefaultCal; + QAction *saveCal; PortExtension portExtension;