mirror of
https://github.com/jankae/LibreVNA.git
synced 2025-12-06 07:12:10 +01:00
add support for logarithmically spaced calibration points
This commit is contained in:
parent
c1705290ff
commit
8e917faed4
|
|
@ -1606,7 +1606,7 @@ std::vector<Calibration::Type> 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<numPoints;i++) {
|
||||
double f = start + (stop - start) * i / (numPoints - 1);
|
||||
double f;
|
||||
if(!isLog) {
|
||||
f = start + (stop - start) * i / (numPoints - 1);
|
||||
} else {
|
||||
f = start * pow(10.0, i * log10(stop / start) / (numPoints - 1));
|
||||
}
|
||||
Point p;
|
||||
switch(type.type) {
|
||||
case Type::SOLT: p = computeSOLT(f); break;
|
||||
|
|
@ -1852,11 +1858,13 @@ void Calibration::deleteMeasurements()
|
|||
measurements.clear();
|
||||
}
|
||||
|
||||
bool Calibration::hasFrequencyOverlap(std::vector<CalibrationMeasurement::Base *> m, double *startFreq, double *stopFreq, int *points)
|
||||
bool Calibration::hasFrequencyOverlap(std::vector<CalibrationMeasurement::Base *> m, double *startFreq, double *stopFreq, int *points, bool *isLog)
|
||||
{
|
||||
double minResolution = std::numeric_limits<double>::max();
|
||||
double minFreq = 0;
|
||||
double maxFreq = std::numeric_limits<double>::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<CalibrationMeasurement::Base *
|
|||
if(resolution < minResolution) {
|
||||
minResolution = resolution;
|
||||
}
|
||||
// check whether the frequency points are more linear or more logarithmic
|
||||
double minDiff = std::numeric_limits<double>::max();
|
||||
double maxDiff = 0;
|
||||
double minRatio = std::numeric_limits<double>::max();
|
||||
double maxRatio = 0;
|
||||
for(unsigned int i=1;i<meas->numPoints();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<CalibrationMeasurement::Base *
|
|||
if(points) {
|
||||
*points = (maxFreq - minFreq) / minResolution + 1;
|
||||
}
|
||||
if(isLog) {
|
||||
*isLog = logCount > linCount;
|
||||
}
|
||||
if(maxFreq > minFreq) {
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ public:
|
|||
static std::vector<Type> 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<CalibrationMeasurement::Base*> m, double *startFreq = nullptr, double *stopFreq = nullptr, int *points = nullptr);
|
||||
bool hasFrequencyOverlap(std::vector<CalibrationMeasurement::Base*> m, double *startFreq = nullptr, double *stopFreq = nullptr, int *points = nullptr, bool *isLog = nullptr);
|
||||
// returns all measurements that match the paramaters
|
||||
std::vector<CalibrationMeasurement::Base*> findMeasurements(CalibrationMeasurement::Base::Type type, int port1 = 0, int port2 = 0);
|
||||
// returns the first measurement in the list that matches the parameters
|
||||
|
|
|
|||
|
|
@ -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<double>::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<double>::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<double>::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;}
|
||||
|
|
|
|||
Loading…
Reference in a new issue