diff --git a/Software/PC_Application/Calibration/calibration2.cpp b/Software/PC_Application/Calibration/calibration2.cpp new file mode 100644 index 0000000..adfed56 --- /dev/null +++ b/Software/PC_Application/Calibration/calibration2.cpp @@ -0,0 +1,84 @@ +#include "calibration2.h" +#include "ui_calibrationdialogui.h" + +#include +#include + +using namespace std; + +Calibration2::Calibration2() +{ + +} + +void Calibration2::edit() +{ + auto d = new QDialog(); + auto ui = new Ui::CalibrationDialog; + ui->setupUi(d); + + QObject::connect(ui->bDelete, &QPushButton::clicked, [=](){ + auto row = ui->table->currentRow(); + if(row >= 0) { + delete measurements[row]; + measurements.erase(measurements.begin() + row); +// updateMeasurementTable(); + } + }); + + QObject::connect(ui->bMoveUp, &QPushButton::clicked, [=](){ + auto row = ui->table->currentRow(); + if(row >= 1) { + swap(measurements[row], measurements[row-1]); + ui->table->selectRow(row-1); +// updateMeasurementTable(); + } + }); + + QObject::connect(ui->bMoveDown, &QPushButton::clicked, [=](){ + auto row = ui->table->currentRow(); + if(row >= 1) { + swap(measurements[row], measurements[row-1]); + ui->table->selectRow(row+1); +// updateMeasurementTable(); + } + }); + +// connect(ui->table, &QTableWidget::currentRowChanged, this, &CalibrationDialog::updateTableEditButtons); + + auto addMenu = new QMenu(); + for(auto t : CalibrationMeasurement::Base::availableTypes()) { + auto action = new QAction(CalibrationMeasurement::Base::TypeToString(t)); + QObject::connect(action, &QAction::triggered, [=](){ + auto newMeas = newMeasurement(t); + if(newMeas) { + measurements.push_back(newMeas); +// updateMeasurementTable(); + } + }); + addMenu->addAction(action); + } + + ui->bAdd->setMenu(addMenu); + +// updateMeasurementTable(); + + d->show(); +} + +CalibrationMeasurement::Base *Calibration2::newMeasurement(CalibrationMeasurement::Base::Type type) +{ + CalibrationMeasurement::Base *m = nullptr; + switch(type) { + case CalibrationMeasurement::Base::Type::Open: m = new CalibrationMeasurement::Open(this); break; + case CalibrationMeasurement::Base::Type::Short: m = new CalibrationMeasurement::Short(this); break; + case CalibrationMeasurement::Base::Type::Load: m = new CalibrationMeasurement::Load(this); break; + case CalibrationMeasurement::Base::Type::Through: m = new CalibrationMeasurement::Through(this); break; + } + return m; +} + +Calkit &Calibration2::getKit() +{ + return kit; +} diff --git a/Software/PC_Application/Calibration/calibration2.h b/Software/PC_Application/Calibration/calibration2.h new file mode 100644 index 0000000..9c290f1 --- /dev/null +++ b/Software/PC_Application/Calibration/calibration2.h @@ -0,0 +1,25 @@ +#ifndef CALIBRATION2_H +#define CALIBRATION2_H + +#include "savable.h" +#include "calibrationmeasurement.h" +#include "calkit.h" + +class Calibration2 : public Savable +{ +public: + Calibration2(); + + void edit(); + + Calkit& getKit(); + +private: + CalibrationMeasurement::Base *newMeasurement(CalibrationMeasurement::Base::Type type); + + std::vector measurements; + + Calkit kit; +}; + +#endif // CALIBRATION2_H diff --git a/Software/PC_Application/Calibration/calibrationdialogui.ui b/Software/PC_Application/Calibration/calibrationdialogui.ui new file mode 100644 index 0000000..377c95c --- /dev/null +++ b/Software/PC_Application/Calibration/calibrationdialogui.ui @@ -0,0 +1,247 @@ + + + CalibrationDialog + + + + 0 + 0 + 912 + 438 + + + + Calibration Measurements + + + true + + + + + + Measurements + + + + + + + + + 0 + 0 + + + + Create default measurements for: + + + + + + + + + + + + + 1 Port SOL calibration + + + + + 2 Port SOLT calibration + + + + + 3 Port SOLT calibration + + + + + 4 Port SOLT calibration + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Add + + + Add + + + + :/icons/add.png:/icons/add.png + + + + + + + false + + + + 0 + 0 + + + + Delete + + + Delete + + + + :/icons/remove.png:/icons/remove.png + + + + + + + false + + + Move up + + + + + + + :/icons/up.png:/icons/up.png + + + + + + + false + + + Move down + + + + + + + :/icons/down.png:/icons/down.png + + + + + + + Measure + + + + :/icons/play.png:/icons/play.png + + + + + + + Clear + + + + :/icons/trash.png:/icons/trash.png + + + + + + + Qt::Vertical + + + + 18 + 186 + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + CalibrationDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + CalibrationDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/Software/PC_Application/Calibration/calibrationmeasurement.cpp b/Software/PC_Application/Calibration/calibrationmeasurement.cpp new file mode 100644 index 0000000..fe6cdce --- /dev/null +++ b/Software/PC_Application/Calibration/calibrationmeasurement.cpp @@ -0,0 +1,331 @@ +#include "calibrationmeasurement.h" +#include "unit.h" +#include "calibration2.h" + +#include + +using namespace std; + +CalibrationMeasurement::Base::Base(Calibration2 *cal) + : cal(cal) +{ + standard = nullptr; + timestamp = QDateTime(); +} + +bool CalibrationMeasurement::Base::setFirstSupportedStandard() +{ + // assign first valid standard + for(auto s : cal->getKit().getStandards()) { + if(supportedStandards().count(s->getType())) { + setStandard(s); + break; + } + } +} + +bool CalibrationMeasurement::Base::setStandard(CalStandard::Virtual *standard) +{ + if(standard) { + if(supportedStandards().count(standard->getType())) { + // can use this standard + this->standard = standard; + return true; + } else { + // can't use this standard, leave unchanged + return false; + } + } else { + // nullptr passed, remove currently used standard + this->standard = nullptr; + return true; + } +} + +QString CalibrationMeasurement::Base::getStatistics() +{ + if(numPoints() > 0) { + QString data = QString::number(numPoints()); + data.append(" points from "); + data.append(Unit::ToString(minFreq(), "Hz", " kMG")); + data.append(" to "); + data.append(Unit::ToString(maxFreq(), "Hz", " kMG")); + return data; + } else { + return "Not available"; + } +} + +std::vector CalibrationMeasurement::Base::availableTypes() +{ + std::vector ret; + for(int i=0;i<(int) Type::Last;i++) { + ret.push_back((Type) i); + } + return ret; +} + +QString CalibrationMeasurement::Base::TypeToString(CalibrationMeasurement::Base::Type type) +{ + switch(type) { + case Type::Open: return "Open"; + case Type::Short: return "Short"; + case Type::Load: return "Load"; + case Type::Through: return "Through"; + case Type::Last: return "Invalid"; + } +} + +CalibrationMeasurement::Base::Type CalibrationMeasurement::Base::TypeFromString(QString s) +{ + for(int i=0;i<(int) Type::Last;i++) { + if(TypeToString((Type) i) == s) { + return (Type) i; + } + } + return Type::Last; +} + +nlohmann::json CalibrationMeasurement::Base::toJSON() +{ + nlohmann::json j; + if(standard) { + j["standard"] = standard->getID(); + } + j["timestamp"] = timestamp.toSecsSinceEpoch(); + return j; +} + +void CalibrationMeasurement::Base::fromJSON(nlohmann::json j) +{ + if(j.contains("standard")) { + // TODO find standard from ID + } + timestamp = QDateTime::fromSecsSinceEpoch(j.value("timestamp", 0)); +} + +bool CalibrationMeasurement::Base::canMeasureSimultaneously(std::vector measurements) +{ + std::set usedPorts; + for(auto m : measurements) { + std::vector ports; + switch(m->getType()) { + case Type::Open: + case Type::Short: + case Type::Load: + // Uses one port + ports.push_back(static_cast(m)->getPort()); + break; + case Type::Through: + // Uses two ports + ports.push_back(static_cast(m)->getPort1()); + ports.push_back(static_cast(m)->getPort2()); + break; + } + for(auto p : ports) { + if(usedPorts.count(p)) { + // port already used for another measurement + return false; + } else { + usedPorts.insert(p); + } + } + } + // if we get here, no port collisions occurred + return true; +} + +double CalibrationMeasurement::OnePort::minFreq() +{ + if(points.size() > 0) { + return points.front().frequency; + } else { + return numeric_limits::max(); + } +} + +double CalibrationMeasurement::OnePort::maxFreq() +{ + if(points.size() > 0) { + return points.back().frequency; + } else { + return 0; + } +} + +void CalibrationMeasurement::OnePort::clearPoints() +{ + points.clear(); + timestamp = QDateTime(); +} + +void CalibrationMeasurement::OnePort::addPoint(const VirtualDevice::VNAMeasurement &m) +{ + QString measurementName = "S"+QString::number(port)+QString::number(port); + if(m.measurements.count(measurementName) > 0) { + Point p; + p.frequency = m.frequency; + p.S = m.measurements.at(measurementName); + points.push_back(p); + timestamp = QDateTime::currentDateTimeUtc(); + } +} + +nlohmann::json CalibrationMeasurement::OnePort::toJSON() +{ + auto j = Base::toJSON(); + j["port"] = port; + nlohmann::json jpoints; + for(auto &p : points) { + nlohmann::json jpoint; + jpoint["frequency"] = p.frequency; + jpoint["real"] = p.S.real(); + jpoint["imag"] = p.S.imag(); + jpoints.push_back(jpoint); + } + j["points"] = jpoints; + return j; +} + +void CalibrationMeasurement::OnePort::fromJSON(nlohmann::json j) +{ + clearPoints(); + Base::fromJSON(j); + port = j.value("port", 0); + if(j.contains("points")) { + for(auto jpoint : j["points"]) { + Point p; + p.frequency = jpoint.value("frequency", 0.0); + p.S = complex(jpoint.value("real", 0.0), jpoint.value("imag", 0.0)); + points.push_back(p); + } + } +} + +std::complex CalibrationMeasurement::OnePort::getMeasured(double frequency) +{ + if(points.size() == 0 || frequency < points.front().frequency || frequency > points.back().frequency) { + return numeric_limits>::quiet_NaN(); + } + // frequency within points, interpolate + auto lower = lower_bound(points.begin(), points.end(), frequency, [](const Point &lhs, double rhs) -> bool { + return lhs.frequency < rhs; + }); + auto lowPoint = *lower; + advance(lower, 1); + auto highPoint = *lower; + double alpha = (frequency - lowPoint.frequency) / (highPoint.frequency - lowPoint.frequency); + complex ret; + return lowPoint.S * (1.0 - alpha) + highPoint.S * alpha; +} + +std::complex CalibrationMeasurement::OnePort::getActual(double frequency) +{ + return static_cast(standard)->toS11(frequency); +} + +int CalibrationMeasurement::OnePort::getPort() const +{ + return port; +} + +double CalibrationMeasurement::TwoPort::minFreq() +{ + if(points.size() > 0) { + return points.front().frequency; + } else { + return numeric_limits::max(); + } +} + +double CalibrationMeasurement::TwoPort::maxFreq() +{ + if(points.size() > 0) { + return points.back().frequency; + } else { + return 0; + } +} + +void CalibrationMeasurement::TwoPort::clearPoints() +{ + points.clear(); + timestamp = QDateTime(); +} + +void CalibrationMeasurement::TwoPort::addPoint(const VirtualDevice::VNAMeasurement &m) +{ + Point p; + p.frequency = m.frequency; + p.S = m.toSparam(port1, port2); + points.push_back(p); + timestamp = QDateTime::currentDateTimeUtc(); +} + +nlohmann::json CalibrationMeasurement::TwoPort::toJSON() +{ + auto j = Base::toJSON(); + j["port1"] = port1; + j["port2"] = port2; + nlohmann::json jpoints; + for(auto &p : points) { + nlohmann::json jpoint; + jpoint["frequency"] = p.frequency; + jpoint["Sparam"] = p.S.toJSON(); + jpoints.push_back(jpoint); + } + j["points"] = jpoints; + return j; +} + +void CalibrationMeasurement::TwoPort::fromJSON(nlohmann::json j) +{ + clearPoints(); + Base::fromJSON(j); + port1 = j.value("port1", 0); + port2 = j.value("port2", 0); + if(j.contains("points")) { + for(auto jpoint : j["points"]) { + Point p; + p.frequency = jpoint.value("frequency", 0.0); + p.S.fromJSON(j["Sparam"]); + points.push_back(p); + } + } +} + +Sparam CalibrationMeasurement::TwoPort::getMeasured(double frequency) +{ + if(points.size() == 0 || frequency < points.front().frequency || frequency > points.back().frequency) { + return Sparam(); + } + // frequency within points, interpolate + auto lower = lower_bound(points.begin(), points.end(), frequency, [](const Point &lhs, double rhs) -> bool { + return lhs.frequency < rhs; + }); + auto lowPoint = *lower; + advance(lower, 1); + auto highPoint = *lower; + double alpha = (frequency - lowPoint.frequency) / (highPoint.frequency - lowPoint.frequency); + Sparam ret; + ret.m11 = lowPoint.S.m11 * (1.0 - alpha) + highPoint.S.m11 * alpha; + ret.m12 = lowPoint.S.m12 * (1.0 - alpha) + highPoint.S.m12 * alpha; + ret.m21 = lowPoint.S.m21 * (1.0 - alpha) + highPoint.S.m21 * alpha; + ret.m22 = lowPoint.S.m22 * (1.0 - alpha) + highPoint.S.m22 * alpha; + return ret; +} + +Sparam CalibrationMeasurement::TwoPort::getActual(double frequency) +{ + return static_cast(standard)->toSparam(frequency); +} + +int CalibrationMeasurement::TwoPort::getPort2() const +{ + return port2; +} + +int CalibrationMeasurement::TwoPort::getPort1() const +{ + return port1; +} diff --git a/Software/PC_Application/Calibration/calibrationmeasurement.h b/Software/PC_Application/Calibration/calibrationmeasurement.h new file mode 100644 index 0000000..a72089b --- /dev/null +++ b/Software/PC_Application/Calibration/calibrationmeasurement.h @@ -0,0 +1,157 @@ +#ifndef CALIBRATIONMEASUREMENT_H +#define CALIBRATIONMEASUREMENT_H + +#include "calstandard.h" +#include "Device/virtualdevice.h" + +#include + +class Calibration2; + +namespace CalibrationMeasurement { + +class Base : public Savable +{ +public: + Base(Calibration2 *cal); + + enum class Type { + Open, + Short, + Load, + Through, + Last, + }; + + bool setFirstSupportedStandard(); + bool setStandard(CalStandard::Virtual *standard); + + QString getStatistics(); + + virtual double minFreq() = 0; + virtual double maxFreq() = 0; + virtual unsigned int numPoints() = 0; + + static std::vector availableTypes(); + static QString TypeToString(Type type); + static Type TypeFromString(QString s); + virtual std::set supportedStandards() = 0; + virtual Type getType() = 0; + virtual void clearPoints() = 0; + virtual void addPoint(const VirtualDevice::VNAMeasurement &m) = 0; + + virtual nlohmann::json toJSON() override; + virtual void fromJSON(nlohmann::json j) override; + + static bool canMeasureSimultaneously(std::vector measurements); +protected: + CalStandard::Virtual *standard; + QDateTime timestamp; + Calibration2 *cal; +}; + +class OnePort : public Base +{ +public: + OnePort(Calibration2 *cal) : + Base(cal), + port(0) {} + + virtual double minFreq() override; + virtual double maxFreq() override; + virtual unsigned int numPoints() override {return points.size();} + + virtual void clearPoints(); + virtual void addPoint(const VirtualDevice::VNAMeasurement &m); + + virtual nlohmann::json toJSON() override; + virtual void fromJSON(nlohmann::json j) override; + + std::complex getMeasured(double frequency); + std::complex getActual(double frequency); + + int getPort() const; + +protected: + int port; + class Point { + public: + double frequency; + std::complex S; + }; + std::vector points; +}; + +class Open : public OnePort +{ +public: + Open(Calibration2 *cal) : + OnePort(cal){setFirstSupportedStandard();} + + virtual std::set supportedStandards() override {return {CalStandard::Virtual::Type::Open};} + virtual Type getType() override {return Type::Open;} +}; + +class Short : public OnePort +{ +public: + Short(Calibration2 *cal) : + OnePort(cal){setFirstSupportedStandard();} + virtual std::set supportedStandards() override {return {CalStandard::Virtual::Type::Short};} + virtual Type getType() override {return Type::Short;} +}; + +class Load : public OnePort +{ +public: + Load(Calibration2 *cal) : + OnePort(cal){setFirstSupportedStandard();} + virtual std::set supportedStandards() override {return {CalStandard::Virtual::Type::Load};} + virtual Type getType() override {return Type::Load;} +}; + +class TwoPort : public Base +{ +public: + TwoPort(Calibration2 *cal) : + Base(cal), + port1(0), + port2(0){} + + virtual double minFreq() override; + virtual double maxFreq() override; + virtual unsigned int numPoints() override {return points.size();} + + virtual void clearPoints(); + virtual void addPoint(const VirtualDevice::VNAMeasurement &m); + + virtual nlohmann::json toJSON() override; + virtual void fromJSON(nlohmann::json j) override; + + Sparam getMeasured(double frequency); + Sparam getActual(double frequency); + + int getPort1() const; + int getPort2() const; + +protected: + int port1, port2; + class Point { + public: + double frequency; + Sparam S; + }; + std::vector points; +}; + +class Through : public TwoPort +{ +public: + Through(Calibration2 *cal) : + TwoPort(cal){setFirstSupportedStandard();} + virtual std::set supportedStandards() override {return {CalStandard::Virtual::Type::Through};} + virtual Type getType() override {return Type::Through;} +}; + +} +#endif // CALIBRATIONMEASUREMENT_H diff --git a/Software/PC_Application/Calibration/calkit.cpp b/Software/PC_Application/Calibration/calkit.cpp index 5dc8ca6..27dbb6f 100644 --- a/Software/PC_Application/Calibration/calkit.cpp +++ b/Software/PC_Application/Calibration/calkit.cpp @@ -417,3 +417,8 @@ void Calkit::clearStandards() } standards.clear(); } + +std::vector Calkit::getStandards() const +{ + return standards; +} diff --git a/Software/PC_Application/Calibration/calkit.h b/Software/PC_Application/Calibration/calkit.h index fbf7787..6d0b226 100644 --- a/Software/PC_Application/Calibration/calkit.h +++ b/Software/PC_Application/Calibration/calkit.h @@ -51,6 +51,8 @@ public: bool checkIfValid(double min_freq, double max_freq, bool isTRL, bool include_male, bool include_female); bool isTRLReflectionShort() const; + std::vector getStandards() const; + private: void clearStandards(); QString manufacturer, serialnumber, description; diff --git a/Software/PC_Application/Calibration/calstandard.cpp b/Software/PC_Application/Calibration/calstandard.cpp index 44f8a72..c4234e5 100644 --- a/Software/PC_Application/Calibration/calstandard.cpp +++ b/Software/PC_Application/Calibration/calstandard.cpp @@ -4,20 +4,31 @@ #include "ui_CalStandardLoadEditDialog.h" #include "ui_CalStandardThroughEditDialog.h" #include "unit.h" +#include "Util/util.h" using namespace std; using namespace CalStandard; +Virtual::Virtual(QString name) : + name(name), + minFreq(std::numeric_limits::lowest()), + maxFreq(std::numeric_limits::max()) +{ + id = Util::random(numeric_limits::max()); +} + Virtual *Virtual::create(Virtual::Type type) { - Virtual *ret = nullptr; switch(type) { - case Type::Open: ret = new Open; break; - case Type::Short: ret = new Short; break; - case Type::Load: ret = new Load; break; - case Type::Through: ret = new Through; break; + case Type::Open: return new Open; + case Type::Short: return new Short; + case Type::Load: return new Load; + case Type::Through: return new Through; + case Type::Line: // TODO + case Type::Last: + break; } - return ret; + return nullptr; } std::vector Virtual::availableTypes() @@ -60,12 +71,19 @@ nlohmann::json Virtual::toJSON() { nlohmann::json j; j["name"] = name.toStdString(); + j["id"] = id; return j; } void Virtual::fromJSON(nlohmann::json j) { name = QString::fromStdString(j.value("name", "")); + id = j.value("id", id); +} + +unsigned long long Virtual::getID() +{ + return id; } void OnePort::setMeasurement(const Touchstone &ts, int port) diff --git a/Software/PC_Application/Calibration/calstandard.h b/Software/PC_Application/Calibration/calstandard.h index 096b544..d4b356f 100644 --- a/Software/PC_Application/Calibration/calstandard.h +++ b/Software/PC_Application/Calibration/calstandard.h @@ -14,10 +14,7 @@ namespace CalStandard class Virtual : public Savable { public: - Virtual(QString name = "") : - name(name), - minFreq(std::numeric_limits::lowest()), - maxFreq(std::numeric_limits::max()){} + Virtual(QString name = ""); enum class Type { Open, @@ -44,10 +41,13 @@ public: virtual nlohmann::json toJSON() override; virtual void fromJSON(nlohmann::json j) override; + unsigned long long getID(); + protected: QString name; double minFreq; double maxFreq; + unsigned long long id; }; class OnePort : public Virtual diff --git a/Software/PC_Application/Device/virtualdevice.cpp b/Software/PC_Application/Device/virtualdevice.cpp index c254b13..6383892 100644 --- a/Software/PC_Application/Device/virtualdevice.cpp +++ b/Software/PC_Application/Device/virtualdevice.cpp @@ -752,13 +752,13 @@ void VirtualDevice::checkIfAllTransmissionsComplete(std::function c } } -Sparam VirtualDevice::VNAMeasurement::toSparam(int port1, int port2) +Sparam VirtualDevice::VNAMeasurement::toSparam(int port1, int port2) const { Sparam S; - S.m11 = measurements["S"+QString::number(port1)+QString::number(port1)]; - S.m12 = measurements["S"+QString::number(port1)+QString::number(port2)]; - S.m21 = measurements["S"+QString::number(port2)+QString::number(port1)]; - S.m22 = measurements["S"+QString::number(port2)+QString::number(port2)]; + S.m11 = measurements.at("S"+QString::number(port1)+QString::number(port1)); + S.m12 = measurements.at("S"+QString::number(port1)+QString::number(port2)); + S.m21 = measurements.at("S"+QString::number(port2)+QString::number(port1)); + S.m22 = measurements.at("S"+QString::number(port2)+QString::number(port2)); return S; } diff --git a/Software/PC_Application/Device/virtualdevice.h b/Software/PC_Application/Device/virtualdevice.h index a922e95..3aabc49 100644 --- a/Software/PC_Application/Device/virtualdevice.h +++ b/Software/PC_Application/Device/virtualdevice.h @@ -96,7 +96,7 @@ public: }; std::map> measurements; - Sparam toSparam(int port1, int port2); + Sparam toSparam(int port1, int port2) const; void fromSparam(Sparam S, int port1, int port2); VNAMeasurement interpolateTo(const VNAMeasurement &to, double a); }; diff --git a/Software/PC_Application/LibreVNA-GUI.pro b/Software/PC_Application/LibreVNA-GUI.pro index e084622..6565f3d 100644 --- a/Software/PC_Application/LibreVNA-GUI.pro +++ b/Software/PC_Application/LibreVNA-GUI.pro @@ -2,6 +2,8 @@ HEADERS += \ ../VNA_embedded/Application/Communication/Protocol.hpp \ Calibration/amplitudecaldialog.h \ Calibration/calibration.h \ + Calibration/calibration2.h \ + Calibration/calibrationmeasurement.h \ Calibration/calibrationtracedialog.h \ Calibration/calkit.h \ Calibration/calkitdialog.h \ @@ -142,6 +144,8 @@ SOURCES += \ ../VNA_embedded/Application/Communication/Protocol.cpp \ Calibration/amplitudecaldialog.cpp \ Calibration/calibration.cpp \ + Calibration/calibration2.cpp \ + Calibration/calibrationmeasurement.cpp \ Calibration/calibrationtracedialog.cpp \ Calibration/calkit.cpp \ Calibration/calkitdialog.cpp \ @@ -281,6 +285,7 @@ FORMS += \ Calibration/addamplitudepointsdialog.ui \ Calibration/amplitudecaldialog.ui \ Calibration/automaticamplitudedialog.ui \ + Calibration/calibrationdialogui.ui \ Calibration/calibrationtracedialog.ui \ Calibration/calkitdialog.ui \ Calibration/frequencycaldialog.ui \ diff --git a/Software/PC_Application/Tools/parameters.cpp b/Software/PC_Application/Tools/parameters.cpp index bd9e798..b5e715b 100644 --- a/Software/PC_Application/Tools/parameters.cpp +++ b/Software/PC_Application/Tools/parameters.cpp @@ -1,5 +1,7 @@ #include "parameters.h" +using namespace std; + Sparam::Sparam(const Tparam &t) { m11 = t.m12 / t.m22; m21 = Type(1) / t.m22; @@ -41,3 +43,25 @@ ABCDparam::ABCDparam(const Sparam &s, Type Z0) : ABCDparam(s, Z0, Z0) { } + +nlohmann::json Parameters::toJSON() +{ + nlohmann::json j; + j["m11_real"] = m11.real(); + j["m11_imag"] = m11.imag(); + j["m12_real"] = m12.real(); + j["m12_imag"] = m12.imag(); + j["m21_real"] = m21.real(); + j["m21_imag"] = m21.imag(); + j["m22_real"] = m22.real(); + j["m22_imag"] = m22.imag(); + return j; +} + +void Parameters::fromJSON(nlohmann::json j) +{ + m11 = complex(j.value("m11_real", 0.0), j.value("m11_imag", 0.0)); + m12 = complex(j.value("m12_real", 0.0), j.value("m12_imag", 0.0)); + m21 = complex(j.value("m21_real", 0.0), j.value("m21_imag", 0.0)); + m22 = complex(j.value("m22_real", 0.0), j.value("m22_imag", 0.0)); +} diff --git a/Software/PC_Application/Tools/parameters.h b/Software/PC_Application/Tools/parameters.h index 81ca684..fa2c1c6 100644 --- a/Software/PC_Application/Tools/parameters.h +++ b/Software/PC_Application/Tools/parameters.h @@ -1,17 +1,22 @@ #ifndef TPARAM_H #define TPARAM_H +#include "savable.h" + #include using Type = std::complex; -class Parameters { +class Parameters : public Savable { public: Parameters(Type m11, Type m12, Type m21, Type m22) : m11(m11), m12(m12), m21(m21), m22(m22){} Parameters(){} Type m11, m12, m21, m22; + + nlohmann::json toJSON() override; + void fromJSON(nlohmann::json j) override; }; // forward declaration of parameter classes diff --git a/Software/PC_Application/Util/util.cpp b/Software/PC_Application/Util/util.cpp index aea99c1..a762c0a 100644 --- a/Software/PC_Application/Util/util.cpp +++ b/Software/PC_Application/Util/util.cpp @@ -2,6 +2,7 @@ #include "preferences.h" +#include #include void Util::unwrapPhase(std::vector &phase, unsigned int start_index) @@ -79,3 +80,13 @@ double Util::dBuVTodBm(double dBuV) double dBdiff = 10*log10(uVpower*1000); return dBuV + dBdiff; } + +unsigned long long Util::random(unsigned long long max) +{ + static std::random_device os_seed; + static const unsigned long long seed = os_seed(); + static std::mt19937_64 generator(seed); + + std::uniform_int_distribution distribute(0, max); + return distribute(generator); +} diff --git a/Software/PC_Application/Util/util.h b/Software/PC_Application/Util/util.h index ff5ad30..244e0f1 100644 --- a/Software/PC_Application/Util/util.h +++ b/Software/PC_Application/Util/util.h @@ -75,6 +75,8 @@ namespace Util { void linearRegression(const std::vector &input, double &B_0, double &B_1); double distanceToLine(QPointF point, QPointF l1, QPointF l2, QPointF *closestLinePoint = nullptr, double *pointRatio = nullptr); + + unsigned long long random(unsigned long long max); } #endif // UTILH_H