Additional YAxisType: Unwrapped phase

This commit is contained in:
Jan Käberich 2022-01-09 15:41:40 +01:00
parent 4ba02a810f
commit 4d959598b5
7 changed files with 48 additions and 6 deletions

View File

@ -36,6 +36,13 @@ Trace::Trace(QString name, QColor color, LiveParameter live)
dataType = domain;
emit outputTypeChanged(dataType);
});
connect(this, &Trace::outputSamplesChanged, [=](unsigned int begin, unsigned int end){
Q_UNUSED(end);
// some samples changed, delete unwrapped phases from here until the end
if(unwrappedPhase.size() > begin) {
unwrappedPhase.resize(begin);
}
});
}
Trace::~Trace()
@ -919,6 +926,27 @@ Trace::Data Trace::sample(unsigned int index, bool getStepResponse) const
return data;
}
double Trace::getUnwrappedPhase(unsigned int index)
{
if(index >= size()) {
return 0.0;
} else if(index >= unwrappedPhase.size()) {
// unwrapped phase not available for this entry, calculate
// copy wrapped phases first
unsigned int start_index = unwrappedPhase.size();
unwrappedPhase.resize(index + 1);
for(unsigned int i=start_index;i<=index;i++) {
unwrappedPhase[i] = arg(lastMath->getSample(i).y);
}
// unwrap the updated part
if(start_index > 0) {
start_index--;
}
Util::unwrapPhase(unwrappedPhase, start_index);
}
return unwrappedPhase[index];
}
Trace::Data Trace::interpolatedSample(double x)
{
auto data = lastMath->getInterpolatedSample(x);

View File

@ -81,6 +81,7 @@ public:
};
Data sample(unsigned int index, bool getStepResponse = false) const;
double getUnwrappedPhase(unsigned int index);
// returns a (possibly interpolated sample) at a specified frequency/time/power
Data interpolatedSample(double x);
QString getFilename() const;
@ -186,6 +187,7 @@ private:
std::vector<MathInfo> mathOps;
TraceMath *lastMath;
std::vector<double> unwrappedPhase;
void updateLastMath(std::vector<MathInfo>::reverse_iterator start);
};

View File

@ -882,6 +882,7 @@ QString TraceXYPlot::AxisTypeToName(TraceXYPlot::YAxisType type)
case YAxisType::Disabled: return "Disabled";
case YAxisType::Magnitude: return "Magnitude";
case YAxisType::Phase: return "Phase";
case YAxisType::UnwrappedPhase: return "Unwrapped Phase";
case YAxisType::VSWR: return "VSWR";
case YAxisType::Real: return "Real";
case YAxisType::Imaginary: return "Imaginary";
@ -995,6 +996,9 @@ QPointF TraceXYPlot::traceToCoordinate(Trace *t, unsigned int sample, TraceXYPlo
case YAxisType::Phase:
ret.setY(Util::SparamToDegree(data.y));
break;
case YAxisType::UnwrappedPhase:
ret.setY(t->getUnwrappedPhase(sample) * 180.0 / M_PI);
break;
case YAxisType::VSWR:
ret.setY(Util::SparamToVSWR(data.y));
break;
@ -1226,6 +1230,7 @@ QString TraceXYPlot::AxisUnit(TraceXYPlot::YAxisType type)
switch(type) {
case TraceXYPlot::YAxisType::Magnitude: return "dB";
case TraceXYPlot::YAxisType::Phase: return "°";
case TraceXYPlot::YAxisType::UnwrappedPhase: return "°";
case TraceXYPlot::YAxisType::VSWR: return "";
case TraceXYPlot::YAxisType::ImpulseReal: return "";
case TraceXYPlot::YAxisType::ImpulseMag: return "dB";

View File

@ -17,6 +17,7 @@ public:
// S parameter options
Magnitude,
Phase,
UnwrappedPhase,
VSWR,
Real,
Imaginary,

View File

@ -204,6 +204,7 @@ std::set<TraceXYPlot::YAxisType> XYplotAxisDialog::supportedYAxis(TraceXYPlot::X
case TraceXYPlot::XAxisType::Power:
ret.insert(TraceXYPlot::YAxisType::Magnitude);
ret.insert(TraceXYPlot::YAxisType::Phase);
ret.insert(TraceXYPlot::YAxisType::UnwrappedPhase);
ret.insert(TraceXYPlot::YAxisType::VSWR);
ret.insert(TraceXYPlot::YAxisType::Real);
ret.insert(TraceXYPlot::YAxisType::Imaginary);

View File

@ -2,12 +2,17 @@
#include <QVector2D>
void Util::unwrapPhase(std::vector<double> &phase)
void Util::unwrapPhase(std::vector<double> &phase, unsigned int start_index)
{
for (unsigned int i = 1; i < phase.size(); i++) {
double d = phase[i] - phase[i-1];
d = d > M_PI ? d - 2 * M_PI : (d < -M_PI ? d + 2 * M_PI : d);
phase[i] = phase[i-1] + d;
for (unsigned int i = start_index + 1; i < phase.size(); i++) {
int d = trunc(phase[i] - phase[i-1]) / M_PI;
if(d > 0) {
// there is larger than a 180° shift between this and the previous phase
phase[i] -= 2*M_PI*(int)((d+1)/2);
} else if(d < 0) {
// there is larger than a -180° shift between this and the previous phase
phase[i] -= 2*M_PI*(int)((d-1)/2);
}
}
}

View File

@ -66,7 +66,7 @@ namespace Util {
return brightness > 0.6 ? Qt::black : Qt::white;
}
void unwrapPhase(std::vector<double> &phase);
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
void linearRegression(const std::vector<double> &input, double &B_0, double &B_1);