Fix calibration measurement interpolation bug
This commit is contained in:
parent
aaea3cb3a3
commit
e400f62f04
@ -1,6 +1,7 @@
|
|||||||
#include "calibrationmeasurement.h"
|
#include "calibrationmeasurement.h"
|
||||||
#include "unit.h"
|
#include "unit.h"
|
||||||
#include "calibration.h"
|
#include "calibration.h"
|
||||||
|
#include "Util/util.h"
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
@ -336,14 +337,10 @@ std::complex<double> CalibrationMeasurement::OnePort::getMeasured(double frequen
|
|||||||
return numeric_limits<complex<double>>::quiet_NaN();
|
return numeric_limits<complex<double>>::quiet_NaN();
|
||||||
}
|
}
|
||||||
// frequency within points, interpolate
|
// frequency within points, interpolate
|
||||||
auto lower = lower_bound(points.begin(), points.end(), frequency, [](const Point &lhs, double rhs) -> bool {
|
Point interp = Util::interpolate<Point, double>(points, frequency, [](const Point &p)->double{
|
||||||
return lhs.frequency < rhs;
|
return p.frequency;
|
||||||
});
|
});
|
||||||
auto highPoint = *lower;
|
return interp.S;
|
||||||
auto lowPoint = *prev(lower);
|
|
||||||
double alpha = (frequency - lowPoint.frequency) / (highPoint.frequency - lowPoint.frequency);
|
|
||||||
complex<double> ret;
|
|
||||||
return lowPoint.S * (1.0 - alpha) + highPoint.S * alpha;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::complex<double> CalibrationMeasurement::OnePort::getActual(double frequency)
|
std::complex<double> CalibrationMeasurement::OnePort::getActual(double frequency)
|
||||||
@ -522,19 +519,10 @@ Sparam CalibrationMeasurement::TwoPort::getMeasured(double frequency)
|
|||||||
return Sparam();
|
return Sparam();
|
||||||
}
|
}
|
||||||
// frequency within points, interpolate
|
// frequency within points, interpolate
|
||||||
auto lower = lower_bound(points.begin(), points.end(), frequency, [](const Point &lhs, double rhs) -> bool {
|
Point interp = Util::interpolate<Point, double>(points, frequency, [](const Point &p)->double{
|
||||||
return lhs.frequency < rhs;
|
return p.frequency;
|
||||||
});
|
});
|
||||||
auto lowPoint = *lower;
|
return interp.S;
|
||||||
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)
|
Sparam CalibrationMeasurement::TwoPort::getActual(double frequency)
|
||||||
@ -699,15 +687,14 @@ std::complex<double> CalibrationMeasurement::Isolation::getMeasured(double frequ
|
|||||||
}
|
}
|
||||||
portRcv--;
|
portRcv--;
|
||||||
portSrc--;
|
portSrc--;
|
||||||
// find correct point, no interpolation yet
|
// find correct point, interpolate
|
||||||
auto lower = lower_bound(points.begin(), points.end(), frequency, [](const Point &lhs, double rhs) -> bool {
|
Point interp = Util::interpolate<Point, double>(points, frequency, [](const Point &p)->double{
|
||||||
return lhs.frequency < rhs;
|
return p.frequency;
|
||||||
});
|
});
|
||||||
Point p = *lower;
|
if(portRcv >= interp.S.size() || portSrc >= interp.S[portRcv].size()) {
|
||||||
if(portRcv >= p.S.size() || portSrc >= p.S[portRcv].size()) {
|
|
||||||
return numeric_limits<complex<double>>::quiet_NaN();
|
return numeric_limits<complex<double>>::quiet_NaN();
|
||||||
} else {
|
} else {
|
||||||
return p.S[portRcv][portSrc];
|
return interp.S[portRcv][portSrc];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +94,19 @@ public:
|
|||||||
public:
|
public:
|
||||||
double frequency;
|
double frequency;
|
||||||
std::complex<double> S;
|
std::complex<double> S;
|
||||||
|
|
||||||
|
Point operator*(double scalar) const {
|
||||||
|
Point ret;
|
||||||
|
ret.frequency = frequency * scalar;
|
||||||
|
ret.S = S * scalar;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Point operator+(const Point &p) const {
|
||||||
|
Point ret;
|
||||||
|
ret.frequency = frequency + p.frequency;
|
||||||
|
ret.S = S + p.S;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
std::vector<Point> getPoints() const;
|
std::vector<Point> getPoints() const;
|
||||||
|
|
||||||
@ -195,6 +208,19 @@ public:
|
|||||||
public:
|
public:
|
||||||
double frequency;
|
double frequency;
|
||||||
Sparam S;
|
Sparam S;
|
||||||
|
|
||||||
|
Point operator*(double scalar) const {
|
||||||
|
Point ret;
|
||||||
|
ret.frequency = frequency * scalar;
|
||||||
|
ret.S = S * scalar;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Point operator+(const Point &p) const {
|
||||||
|
Point ret;
|
||||||
|
ret.frequency = frequency + p.frequency;
|
||||||
|
ret.S = S + p.S;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
std::vector<Point> getPoints() const;
|
std::vector<Point> getPoints() const;
|
||||||
|
|
||||||
@ -254,6 +280,37 @@ public:
|
|||||||
public:
|
public:
|
||||||
double frequency;
|
double frequency;
|
||||||
std::vector<std::vector<std::complex<double>>> S;
|
std::vector<std::vector<std::complex<double>>> S;
|
||||||
|
|
||||||
|
Point operator*(double scalar) const {
|
||||||
|
Point ret;
|
||||||
|
ret.frequency = frequency * scalar;
|
||||||
|
for(const auto &v1 : S) {
|
||||||
|
std::vector<std::complex<double>> v;
|
||||||
|
for(const auto &s : v1) {
|
||||||
|
v.push_back(s * scalar);
|
||||||
|
}
|
||||||
|
ret.S.push_back(v);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Point operator+(const Point &p) const {
|
||||||
|
Point ret;
|
||||||
|
ret.frequency = frequency + p.frequency;
|
||||||
|
if(S.size() != p.S.size()) {
|
||||||
|
throw std::runtime_error("Points to not have the same number of measurements");
|
||||||
|
}
|
||||||
|
for(unsigned int i=0;i<S.size();i++) {
|
||||||
|
std::vector<std::complex<double>> v;
|
||||||
|
if(S[i].size() != p.S[i].size()) {
|
||||||
|
throw std::runtime_error("Points to not have the same number of measurements");
|
||||||
|
}
|
||||||
|
for(unsigned int j=0;j<S[i].size();j++) {
|
||||||
|
v.push_back(S[i][j] + p.S[i][j]);
|
||||||
|
}
|
||||||
|
ret.S.push_back(v);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
std::vector<Point> getPoints() const;
|
std::vector<Point> getPoints() const;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ public:
|
|||||||
Sparam(const Tparam &t);
|
Sparam(const Tparam &t);
|
||||||
Sparam(const ABCDparam &a, Type Z01, Type Z02);
|
Sparam(const ABCDparam &a, Type Z01, Type Z02);
|
||||||
Sparam(const ABCDparam &a, Type Z0);
|
Sparam(const ABCDparam &a, Type Z0);
|
||||||
Sparam operator+(const Sparam &r) {
|
Sparam operator+(const Sparam &r) const {
|
||||||
Sparam p;
|
Sparam p;
|
||||||
p.m11 = this->m11+r.m11;
|
p.m11 = this->m11+r.m11;
|
||||||
p.m12 = this->m12+r.m12;
|
p.m12 = this->m12+r.m12;
|
||||||
@ -38,7 +38,7 @@ public:
|
|||||||
p.m22 = this->m22+r.m22;
|
p.m22 = this->m22+r.m22;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
Sparam operator*(const Type &r) {
|
Sparam operator*(const Type &r) const {
|
||||||
Sparam p(m11*r, m12*r, m21*r, m22*r);
|
Sparam p(m11*r, m12*r, m21*r, m22*r);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ TraceModel::TraceModel(QObject *parent)
|
|||||||
{
|
{
|
||||||
traces.clear();
|
traces.clear();
|
||||||
source = DataSource::Unknown;
|
source = DataSource::Unknown;
|
||||||
|
lastSweepPosition = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceModel::~TraceModel()
|
TraceModel::~TraceModel()
|
||||||
|
@ -69,6 +69,42 @@ namespace Util {
|
|||||||
return brightness > 0.6 ? Qt::black : Qt::white;
|
return brightness > 0.6 ? Qt::black : Qt::white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Performs interpolation of a list of sorted values.
|
||||||
|
* T: type of the elements in the list. Must contain a value by which these elements are sorted in the list.
|
||||||
|
* C: Target value of the interpolation (e.g. frequency).
|
||||||
|
* extract: A function returning the "sorted by"-value of the element
|
||||||
|
*
|
||||||
|
* The following operators must be defined:
|
||||||
|
* T*double
|
||||||
|
* T+T
|
||||||
|
*
|
||||||
|
* Will return an interpolated element T. If no interpolation is possible because target is outside
|
||||||
|
* of the list, either the first or last element in the list is returned instead.
|
||||||
|
*/
|
||||||
|
template<typename T, typename C>
|
||||||
|
T interpolate(const std::vector<T> &list, C target, std::function<C(const T &lhs)> extract) {
|
||||||
|
T ret = {};
|
||||||
|
if(list.size() > 0) {
|
||||||
|
auto it = std::lower_bound(list.begin(), list.end(), target, [=](const T &lhs, C rhs)->bool{
|
||||||
|
return extract(lhs) < rhs;
|
||||||
|
});
|
||||||
|
if(it == list.begin()) {
|
||||||
|
// just return the first element
|
||||||
|
ret = list.front();
|
||||||
|
} else if(it == list.end()) {
|
||||||
|
// outside of the list of provided values, just use the last one
|
||||||
|
ret = list.back();
|
||||||
|
} else {
|
||||||
|
// needs to interpolate
|
||||||
|
auto highPoint = *it;
|
||||||
|
auto lowPoint = *std::prev(it);
|
||||||
|
double alpha = (target - extract(lowPoint)) / (extract(highPoint) - extract(lowPoint));
|
||||||
|
ret = lowPoint * (1.0 - alpha) + highPoint * alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
void unwrapPhase(std::vector<double> &phase, unsigned int start_index = 0);
|
void unwrapPhase(std::vector<double> &phase, unsigned int start_index = 0);
|
||||||
|
|
||||||
// input values are Y coordinates, assumes evenly spaced linear X values from 0 to input.size() - 1
|
// input values are Y coordinates, assumes evenly spaced linear X values from 0 to input.size() - 1
|
||||||
|
530737
Software/PC_Application/LibreVNA-GUI/callgrind.out.25779
Normal file
530737
Software/PC_Application/LibreVNA-GUI/callgrind.out.25779
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user