diff --git a/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.cpp b/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.cpp index f7bfba2..24bb4d1 100644 --- a/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.cpp @@ -1606,7 +1606,7 @@ std::vector Calibration::getTypes() return types; } -bool Calibration::canCompute(Calibration::CalType type, double *startFreq, double *stopFreq, int *points) +bool Calibration::canCompute(Calibration::CalType type, double *startFreq, double *stopFreq, int *points, bool *isLog) { using RequiredMeasurements = struct { CalibrationMeasurement::Base::Type type; @@ -1676,7 +1676,7 @@ bool Calibration::canCompute(Calibration::CalType type, double *startFreq, doubl foundMeasurements.push_back(meas); } } - return hasFrequencyOverlap(foundMeasurements, startFreq, stopFreq, points); + return hasFrequencyOverlap(foundMeasurements, startFreq, stopFreq, points, isLog); } return false; } @@ -1690,14 +1690,20 @@ bool Calibration::compute(Calibration::CalType type) } double start, stop; int numPoints; - if(!canCompute(type, &start, &stop, &numPoints)) { + bool isLog; + if(!canCompute(type, &start, &stop, &numPoints, &isLog)) { return false; } caltype = type; try { points.clear(); for(int i=0;i m, double *startFreq, double *stopFreq, int *points) +bool Calibration::hasFrequencyOverlap(std::vector m, double *startFreq, double *stopFreq, int *points, bool *isLog) { double minResolution = std::numeric_limits::max(); double minFreq = 0; double maxFreq = std::numeric_limits::max(); + unsigned int logCount = 0; + unsigned int linCount = 0; for(auto meas : m) { if(meas->numPoints() < 2) { return false; @@ -1871,6 +1879,38 @@ bool Calibration::hasFrequencyOverlap(std::vector::max(); + double maxDiff = 0; + double minRatio = std::numeric_limits::max(); + double maxRatio = 0; + for(unsigned int i=1;inumPoints();i++) { + double f_prev = meas->getPointFreq(i-1); + double f_next = meas->getPointFreq(i); + double diff = f_next - f_prev; + double ratio = f_next / f_prev; + if(diff < minDiff) { + minDiff = diff; + } + if(diff > maxDiff) { + maxDiff = diff; + } + if(ratio < minRatio) { + minRatio = ratio; + } + if(ratio > maxRatio) { + maxRatio = ratio; + } + } + double diffVariationNormalized = (maxDiff - minDiff) / maxDiff; + double ratioVariationNormalized = (maxRatio - minRatio) / maxRatio; + if(abs(diffVariationNormalized) < abs(ratioVariationNormalized)) { + // more linear + linCount++; + } else { + // more logarithmic + logCount++; + } } if(startFreq) { *startFreq = minFreq; @@ -1881,6 +1921,9 @@ bool Calibration::hasFrequencyOverlap(std::vector linCount; + } if(maxFreq > minFreq) { return true; } else { diff --git a/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.h b/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.h index 733f723..07946b7 100644 --- a/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.h +++ b/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.h @@ -62,7 +62,7 @@ public: static std::vector getTypes(); // Checks whether all measurements for a specific calibration are available. // If pointer to the frequency/points variables are given, the start/stop frequency and number of points the calibration will have after the calculation is stored there - bool canCompute(CalType type, double *startFreq = nullptr, double *stopFreq = nullptr, int *points = nullptr); + bool canCompute(CalType type, double *startFreq = nullptr, double *stopFreq = nullptr, int *points = nullptr, bool *isLog = nullptr); // Resets the calibration (deletes all measurements and calculated coefficients) void reset(); // Returns the minimum number of ports for a given calibration type. @@ -130,7 +130,7 @@ private: void createDefaultMeasurements(DefaultMeasurements dm); void deleteMeasurements(); - bool hasFrequencyOverlap(std::vector m, double *startFreq = nullptr, double *stopFreq = nullptr, int *points = nullptr); + bool hasFrequencyOverlap(std::vector m, double *startFreq = nullptr, double *stopFreq = nullptr, int *points = nullptr, bool *isLog = nullptr); // returns all measurements that match the paramaters std::vector findMeasurements(CalibrationMeasurement::Base::Type type, int port1 = 0, int port2 = 0); // returns the first measurement in the list that matches the parameters diff --git a/Software/PC_Application/LibreVNA-GUI/Calibration/calibrationmeasurement.h b/Software/PC_Application/LibreVNA-GUI/Calibration/calibrationmeasurement.h index ed1602f..8161e8b 100644 --- a/Software/PC_Application/LibreVNA-GUI/Calibration/calibrationmeasurement.h +++ b/Software/PC_Application/LibreVNA-GUI/Calibration/calibrationmeasurement.h @@ -41,6 +41,7 @@ public: virtual double maxUsableFreq() = 0; virtual double minFreq() = 0; virtual double maxFreq() = 0; + virtual double getPointFreq(unsigned int p) = 0; virtual unsigned int numPoints() = 0; virtual bool readyForMeasurement() {return false;} virtual bool readyForCalculation() {return false;} @@ -88,6 +89,7 @@ public: virtual double maxUsableFreq() override; virtual double minFreq() override {return points.size() > 0 ? points.front().frequency : std::numeric_limits::max();} virtual double maxFreq() override {return points.size() > 0 ? points.back().frequency : 0;} + virtual double getPointFreq(unsigned int p) override { return p < points.size() ? points[p].frequency : 0;} virtual unsigned int numPoints() override {return points.size();} virtual bool readyForMeasurement() override {return standard != nullptr;} virtual bool readyForCalculation() override {return standard && points.size() > 0;} @@ -207,6 +209,7 @@ public: virtual double maxUsableFreq() override; virtual double minFreq() override {return points.size() > 0 ? points.front().frequency : std::numeric_limits::max();} virtual double maxFreq() override {return points.size() > 0 ? points.back().frequency : 0;} + virtual double getPointFreq(unsigned int p) override { return p < points.size() ? points[p].frequency : 0;} virtual unsigned int numPoints() override {return points.size();} virtual bool readyForMeasurement() override {return standard != nullptr;} virtual bool readyForCalculation() override {return standard && points.size() > 0;} @@ -281,6 +284,7 @@ public: virtual double maxUsableFreq() override {return maxFreq();} virtual double minFreq() override {return points.size() > 0 ? points.front().frequency : std::numeric_limits::max();} virtual double maxFreq() override {return points.size() > 0 ? points.back().frequency : 0;} + virtual double getPointFreq(unsigned int p) override { return p < points.size() ? points[p].frequency : 0;} virtual unsigned int numPoints() override; virtual bool readyForMeasurement() override {return true;} virtual bool readyForCalculation() override {return points.size() > 0;}