Calculate additional parameters (R/L/C,...) for markers and traces
This commit is contained in:
parent
a232be3443
commit
e27e594435
@ -10,6 +10,7 @@
|
||||
#include "json.hpp"
|
||||
#include <fstream>
|
||||
#include <CustomWidgets/informationbox.h>
|
||||
#include "Util/util.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace nlohmann;
|
||||
@ -416,7 +417,7 @@ void AmplitudeCalDialog::ReceivedMeasurement(Protocol::SpectrumAnalyzerResult re
|
||||
if(measured.size() >= averages) {
|
||||
measured.pop_front();
|
||||
}
|
||||
MeasurementResult m = {.port1 = Unit::dB(res.port1), .port2 = Unit::dB(res.port2)};
|
||||
MeasurementResult m = {.port1 = Util::SparamTodB(res.port1), .port2 = Util::SparamTodB(res.port2)};
|
||||
measured.push_back(m);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <QDebug>
|
||||
#include <QButtonGroup>
|
||||
#include <complex>
|
||||
#include "unit.h"
|
||||
#include "Util/util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -207,8 +207,8 @@ void ManualControlDialog::NewStatus(Protocol::ManualStatus status)
|
||||
|
||||
auto port1referenced = port1 / ref;
|
||||
auto port2referenced = port2 / ref;
|
||||
auto port1db = Unit::dB(port1referenced);
|
||||
auto port2db = Unit::dB(port2referenced);
|
||||
auto port1db = Util::SparamTodB(port1referenced);
|
||||
auto port2db = Util::SparamTodB(port2referenced);
|
||||
|
||||
ui->port1referenced->setText(QString::number(port1db, 'f', 1) + "db@" + QString::number(arg(port1referenced)*180/M_PI, 'f', 0) + "°");
|
||||
ui->port2referenced->setText(QString::number(port2db, 'f', 1) + "db@" + QString::number(arg(port2referenced)*180/M_PI, 'f', 0) + "°");
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "impedancematchdialog.h"
|
||||
#include "ui_impedancematchdialog.h"
|
||||
#include "Tools/eseries.h"
|
||||
#include "unit.h"
|
||||
#include "Util/util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -240,7 +240,7 @@ void ImpedanceMatchDialog::calculateMatch()
|
||||
ui->mReal->setValue(Zmatched.real());
|
||||
ui->mImag->setValue(Zmatched.imag());
|
||||
double reflection = abs((Zmatched-Z0)/(Zmatched+Z0));
|
||||
auto loss = Unit::dB(reflection);
|
||||
auto loss = Util::SparamTodB(reflection);
|
||||
ui->mLoss->setValue(loss);
|
||||
|
||||
// set correct image
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <QApplication>
|
||||
#include "preferences.h"
|
||||
#include "markergroup.h"
|
||||
#include "Util/util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -110,6 +111,10 @@ QString Marker::formatToString(Marker::Format f)
|
||||
case Format::RealImag: return "real + imag";
|
||||
case Format::Impedance: return "Impedance";
|
||||
case Format::VSWR: return "VSWR";
|
||||
case Format::SeriesR: return "Resistance";
|
||||
case Format::Capacitance: return "Capacitance";
|
||||
case Format::Inductance: return "Inductance";
|
||||
case Format::QualityFactor: return "Quality Factor";
|
||||
case Format::TOI: return "Third order intercept";
|
||||
case Format::AvgTone: return "Average Tone Level";
|
||||
case Format::AvgModulationProduct: return "Average Modulation Product Level";
|
||||
@ -175,6 +180,10 @@ std::vector<Marker::Format> Marker::applicableFormats()
|
||||
if(parentTrace->isReflection()) {
|
||||
ret.push_back(Format::Impedance);
|
||||
ret.push_back(Format::VSWR);
|
||||
ret.push_back(Format::SeriesR);
|
||||
ret.push_back(Format::Capacitance);
|
||||
ret.push_back(Format::Inductance);
|
||||
ret.push_back(Format::QualityFactor);
|
||||
}
|
||||
if(!isnan(parentTrace->getNoise(parentTrace->minX()))) {
|
||||
ret.push_back(Format::Noise);
|
||||
@ -224,12 +233,12 @@ QString Marker::readableData(Format f)
|
||||
if(type != Type::Delta) {
|
||||
switch(f) {
|
||||
case Format::dB:
|
||||
return Unit::ToString(Unit::dB(data), "dB", " ", 4);
|
||||
return Unit::ToString(Util::SparamTodB(data), "dB", " ", 4);
|
||||
case Format::RealImag:
|
||||
return Unit::ToString(data.real(), "", " ", 5) + "+"+Unit::ToString(data.imag(), "", " ", 5)+"j";
|
||||
case Format::Impedance: {
|
||||
auto step = parentTrace->sample(parentTrace->index(position), Trace::SampleType::TimeStep).y.real();
|
||||
auto impedance = 50.0 * (1.0 + step) / (1.0 - step);
|
||||
auto impedance = Util::SparamToImpedance(step).real();
|
||||
return Unit::ToString(impedance, "Ω", "m kM", 3);
|
||||
}
|
||||
break;
|
||||
@ -242,14 +251,14 @@ QString Marker::readableData(Format f)
|
||||
}
|
||||
switch(f) {
|
||||
case Format::dB:
|
||||
return "Δ:"+Unit::ToString(Unit::dB(data) - Unit::dB(delta->data), "dB", " ", 4);
|
||||
return "Δ:"+Unit::ToString(Util::SparamTodB(data) - Util::SparamTodB(delta->data), "dB", " ", 4);
|
||||
case Format::RealImag:
|
||||
return "Δ:"+Unit::ToString(data.real() - delta->data.real(), "", " ", 5) + "+"+Unit::ToString(data.imag() - delta->data.real(), "", " ", 5)+"j";
|
||||
case Format::Impedance: {
|
||||
auto step = parentTrace->sample(parentTrace->index(position), Trace::SampleType::TimeStep).y.real();
|
||||
auto stepDelta = delta->parentTrace->sample(delta->parentTrace->index(delta->position), Trace::SampleType::TimeStep).y.real();
|
||||
auto impedance = 50.0 * (1.0 + step) / (1.0 - step);
|
||||
auto impedanceDelta = 50.0 * (1.0 + stepDelta) / (1.0 - stepDelta);
|
||||
auto impedance = Util::SparamToImpedance(step).real();
|
||||
auto impedanceDelta = Util::SparamToImpedance(stepDelta).real();
|
||||
return "Δ:"+Unit::ToString(impedance - impedanceDelta, "Ω", "m kM", 3);
|
||||
}
|
||||
break;
|
||||
@ -266,9 +275,9 @@ QString Marker::readableData(Format f)
|
||||
return "Invalid delta marker";
|
||||
}
|
||||
switch(f) {
|
||||
case Format::dB: return "Δ:"+Unit::ToString(Unit::dB(data) - Unit::dB(delta->data), "dB", " ", 4);
|
||||
case Format::dB: return "Δ:"+Unit::ToString(Util::SparamTodB(data) - Util::SparamTodB(delta->data), "dB", " ", 4);
|
||||
case Format::dBAngle: {
|
||||
QString ret = "Δ:"+Unit::ToString(Unit::dB(data) - Unit::dB(delta->data), "dB", " ", 4) + "/";
|
||||
QString ret = "Δ:"+Unit::ToString(Util::SparamTodB(data) - Util::SparamTodB(delta->data), "dB", " ", 4) + "/";
|
||||
auto phase = arg(data)*180/M_PI;
|
||||
auto deltaphase = arg(delta->data)*180/M_PI;
|
||||
auto phasediff = phase - deltaphase;
|
||||
@ -282,10 +291,14 @@ QString Marker::readableData(Format f)
|
||||
}
|
||||
case Format::RealImag: return "Δ:"+Unit::ToString(data.real() - delta->data.real(), "", " ", 5) + "+"+Unit::ToString(data.imag() - delta->data.imag(), "", " ", 5)+"j";
|
||||
case Format::Impedance: {
|
||||
auto impedance = 50.0 * (1.0 + data) / (1.0 - data);
|
||||
auto delta_impedance = 50.0 * (1.0 + delta->data) / (1.0 - delta->data);
|
||||
auto impedance = Util::SparamToImpedance(data);
|
||||
auto delta_impedance = Util::SparamToImpedance(delta->data);
|
||||
return "Δ:"+Unit::ToString(impedance.real() - delta_impedance.real(), "Ω", "m k", 5) + "+"+Unit::ToString(impedance.imag() - delta_impedance.imag(), "Ω", "m k", 5)+"j";
|
||||
}
|
||||
case Format::SeriesR: return "Δ:"+Unit::ToString(Util::SparamToResistance(data) - Util::SparamToResistance(delta->data), "Ω", "m kM", 4);
|
||||
case Format::Capacitance: return "Δ:"+Unit::ToString(Util::SparamToCapacitance(data, position) - Util::SparamToCapacitance(delta->data, delta->position), "F", "pnum ", 4);
|
||||
case Format::Inductance: return "Δ:"+Unit::ToString(Util::SparamToInductance(data, position) - Util::SparamToInductance(delta->data, delta->position), "H", "pnum ", 4);
|
||||
case Format::QualityFactor: return "ΔQ:" + Unit::ToString(Util::SparamToQualityFactor(data) - Util::SparamToQualityFactor(delta->data), "", " ", 3);
|
||||
case Format::Noise: return "Δ:"+Unit::ToString(parentTrace->getNoise(position) - delta->parentTrace->getNoise(delta->position), "dbm/Hz", " ", 3);
|
||||
default: return "Invalid";
|
||||
}
|
||||
@ -293,16 +306,20 @@ QString Marker::readableData(Format f)
|
||||
break;
|
||||
default:
|
||||
switch(f) {
|
||||
case Format::dB: return Unit::ToString(Unit::dB(data), "dB", " ", 4);
|
||||
case Format::dBAngle: return Unit::ToString(Unit::dB(data), "dB", " ", 4) + "/"+Unit::ToString(arg(data)*180/M_PI, "°", " ", 4);
|
||||
case Format::dB: return Unit::ToString(Util::SparamTodB(data), "dB", " ", 4);
|
||||
case Format::dBAngle: return Unit::ToString(Util::SparamTodB(data), "dB", " ", 4) + "/"+Unit::ToString(arg(data)*180/M_PI, "°", " ", 4);
|
||||
case Format::RealImag: return Unit::ToString(data.real(), "", " ", 5) + "+"+Unit::ToString(data.imag(), "", " ", 5)+"j";
|
||||
case Format::VSWR:
|
||||
if(abs(data) < 1.0) {
|
||||
return "VSWR: "+Unit::ToString(((1+abs(data)) / (1-abs(data))), ":1", " ", 5);
|
||||
return "VSWR: "+Unit::ToString(Util::SparamToVSWR(data), ":1", " ", 5);
|
||||
} else {
|
||||
return "VSWR: NaN";
|
||||
}
|
||||
break;
|
||||
case Format::SeriesR: return Unit::ToString(Util::SparamToResistance(data), "Ω", "m kM", 4);
|
||||
case Format::Capacitance: return Unit::ToString(Util::SparamToCapacitance(data, position), "F", "pnum ", 4);
|
||||
case Format::Inductance: return Unit::ToString(Util::SparamToInductance(data, position), "H", "pnum ", 4);
|
||||
case Format::QualityFactor: return "Q:" + Unit::ToString(Util::SparamToQualityFactor(data), "", " ", 3);
|
||||
case Format::Noise: return Unit::ToString(parentTrace->getNoise(position), "dbm/Hz", " ", 3);
|
||||
case Format::TOI: {
|
||||
auto avgFundamental = (helperMarkers[0]->toDecibel() + helperMarkers[1]->toDecibel()) / 2;
|
||||
@ -331,7 +348,7 @@ QString Marker::readableData(Format f)
|
||||
if(parentTrace->isReflection()) {
|
||||
return "Calculation not possible with reflection measurement";
|
||||
} else {
|
||||
return "Ins. Loss:"+Unit::ToString(Unit::dB(data), "dB", " ", 3);
|
||||
return "Ins. Loss:"+Unit::ToString(Util::SparamTodB(data), "dB", " ", 3);
|
||||
}
|
||||
case Format::PhaseNoise: {
|
||||
auto carrier = toDecibel();
|
||||
@ -340,7 +357,7 @@ QString Marker::readableData(Format f)
|
||||
}
|
||||
break;
|
||||
case Format::Impedance: {
|
||||
auto impedance = 50.0 * (1.0 + data) / (1.0 - data);
|
||||
auto impedance = Util::SparamToImpedance(data);
|
||||
return Unit::ToString(impedance.real(), "Ω", "m k", 5) + "+"+Unit::ToString(impedance.imag(), "Ω", "m k", 5)+"j";
|
||||
}
|
||||
case Format::CenterBandwidth:
|
||||
@ -853,7 +870,7 @@ void Marker::setType(Marker::Type t)
|
||||
|
||||
double Marker::toDecibel()
|
||||
{
|
||||
return Unit::dB(data);
|
||||
return Util::SparamTodB(data);
|
||||
}
|
||||
|
||||
bool Marker::isVisible()
|
||||
@ -1277,11 +1294,11 @@ void Marker::update()
|
||||
setPosition(peakFreq);
|
||||
// find the cutoff frequency
|
||||
auto index = parentTrace->index(peakFreq);
|
||||
auto peakAmplitude = Unit::dB(parentTrace->sample(index).y);
|
||||
auto peakAmplitude = Util::SparamTodB(parentTrace->sample(index).y);
|
||||
auto cutoff = peakAmplitude + cutoffAmplitude;
|
||||
int inc = type == Type::Lowpass ? 1 : -1;
|
||||
while(index >= 0 && index < (int) parentTrace->size()) {
|
||||
auto amplitude = Unit::dB(parentTrace->sample(index).y);
|
||||
auto amplitude = Util::SparamTodB(parentTrace->sample(index).y);
|
||||
if(amplitude <= cutoff) {
|
||||
break;
|
||||
}
|
||||
@ -1307,12 +1324,12 @@ void Marker::update()
|
||||
setPosition(peakFreq);
|
||||
// find the cutoff frequencies
|
||||
auto index = parentTrace->index(peakFreq);
|
||||
auto peakAmplitude = Unit::dB(parentTrace->sample(index).y);
|
||||
auto peakAmplitude = Util::SparamTodB(parentTrace->sample(index).y);
|
||||
auto cutoff = peakAmplitude + cutoffAmplitude;
|
||||
|
||||
auto low_index = index;
|
||||
while(low_index >= 0) {
|
||||
auto amplitude = Unit::dB(parentTrace->sample(low_index).y);
|
||||
auto amplitude = Util::SparamTodB(parentTrace->sample(low_index).y);
|
||||
if(amplitude <= cutoff) {
|
||||
break;
|
||||
}
|
||||
@ -1326,7 +1343,7 @@ void Marker::update()
|
||||
|
||||
auto high_index = index;
|
||||
while(high_index < (int) parentTrace->size()) {
|
||||
auto amplitude = Unit::dB(parentTrace->sample(high_index).y);
|
||||
auto amplitude = Util::SparamTodB(parentTrace->sample(high_index).y);
|
||||
if(amplitude <= cutoff) {
|
||||
break;
|
||||
}
|
||||
|
@ -27,6 +27,10 @@ public:
|
||||
RealImag,
|
||||
Impedance,
|
||||
VSWR,
|
||||
SeriesR,
|
||||
Capacitance,
|
||||
Inductance,
|
||||
QualityFactor,
|
||||
// Noise marker parameters
|
||||
Noise,
|
||||
PhaseNoise,
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <QLabel>
|
||||
#include <QDebug>
|
||||
#include "ui_tdrexplanationwidget.h"
|
||||
#include "unit.h"
|
||||
#include "Util/util.h"
|
||||
|
||||
using namespace Math;
|
||||
using namespace std;
|
||||
@ -95,7 +95,7 @@ void TDR::edit()
|
||||
|
||||
ui->manualMag->setUnit("dBm");
|
||||
ui->manualMag->setPrecision(3);
|
||||
ui->manualMag->setValue(Unit::dB(manualDC));
|
||||
ui->manualMag->setValue(Util::SparamTodB(manualDC));
|
||||
ui->manualPhase->setUnit("°");
|
||||
ui->manualPhase->setPrecision(4);
|
||||
ui->manualPhase->setValue(180.0/M_PI * arg(manualDC));
|
||||
|
@ -7,8 +7,9 @@
|
||||
#include <QPainter>
|
||||
#include "Util/util.h"
|
||||
#include "Traces/fftcomplex.h"
|
||||
#include "unit.h"
|
||||
#include "Util/util.h"
|
||||
#include <QMouseEvent>
|
||||
#include "unit.h"
|
||||
|
||||
Math::TimeGate::TimeGate()
|
||||
{
|
||||
@ -345,8 +346,8 @@ void Math::TimeGateGraph::paintEvent(QPaintEvent *event)
|
||||
auto last = input[i-1];
|
||||
auto now = input[i];
|
||||
|
||||
auto y_last = Unit::dB(last.y);
|
||||
auto y_now = Unit::dB(now.y);
|
||||
auto y_last = Util::SparamTodB(last.y);
|
||||
auto y_now = Util::SparamTodB(now.y);
|
||||
|
||||
if(std::isnan(y_last) || std::isnan(y_now) || std::isinf(y_last) || std::isinf(y_now)) {
|
||||
continue;
|
||||
@ -366,8 +367,8 @@ void Math::TimeGateGraph::paintEvent(QPaintEvent *event)
|
||||
auto x_last = input[i-1].x;
|
||||
auto x_now = input[i].x;
|
||||
|
||||
auto f_last = Unit::dB(filter[i-1]);
|
||||
auto f_now = Unit::dB(filter[i]);
|
||||
auto f_last = Util::SparamTodB(filter[i-1]);
|
||||
auto f_now = Util::SparamTodB(filter[i]);
|
||||
|
||||
if(std::isnan(f_last) || std::isnan(f_now) || std::isinf(f_last) || std::isinf(f_now)) {
|
||||
continue;
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <QScrollBar>
|
||||
#include <QSettings>
|
||||
#include <functional>
|
||||
#include "unit.h"
|
||||
#include "Util/util.h"
|
||||
#include "Marker/marker.h"
|
||||
|
||||
using namespace std;
|
||||
@ -871,7 +871,7 @@ std::vector<double> Trace::findPeakFrequencies(unsigned int maxPeaks, double min
|
||||
double max_dbm = -200.0;
|
||||
double min_dbm = 200.0;
|
||||
for(auto d : lastMath->rData()) {
|
||||
double dbm = Unit::dB(d.y);
|
||||
double dbm = Util::SparamTodB(d.y);
|
||||
if((dbm >= max_dbm) && (min_dbm <= dbm - minValley)) {
|
||||
// potential peak frequency
|
||||
frequency = d.x;
|
||||
@ -945,7 +945,7 @@ double Trace::getNoise(double frequency)
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
// convert to dbm
|
||||
auto dbm = Unit::dB(lastMath->getInterpolatedSample(frequency).y);
|
||||
auto dbm = Util::SparamTodB(lastMath->getInterpolatedSample(frequency).y);
|
||||
// convert to 1Hz bandwidth
|
||||
dbm -= 10*log10(settings.SA.RBW);
|
||||
return dbm;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <QDebug>
|
||||
#include <QMenu>
|
||||
#include "unit.h"
|
||||
#include "Util/util.h"
|
||||
|
||||
TraceWidget::TraceWidget(TraceModel &model, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
@ -172,7 +173,7 @@ void TraceWidget::SetupSCPI()
|
||||
if(std::isnan(d.x)) {
|
||||
return "NaN";
|
||||
}
|
||||
return QString::number(Unit::dB(d.y.real()));
|
||||
return QString::number(Util::SparamTodB(d.y.real()));
|
||||
} else {
|
||||
if(std::isnan(d.x)) {
|
||||
return "NaN,NaN";
|
||||
|
@ -764,13 +764,18 @@ TraceXYPlot::XAxisMode TraceXYPlot::AxisModeFromName(QString name)
|
||||
QString TraceXYPlot::AxisTypeToName(TraceXYPlot::YAxisType type)
|
||||
{
|
||||
switch(type) {
|
||||
case YAxisType::Magnitude: return "Magnitude"; break;
|
||||
case YAxisType::Phase: return "Phase"; break;
|
||||
case YAxisType::VSWR: return "VSWR"; break;
|
||||
case YAxisType::ImpulseReal: return "Impulse Response (Real)"; break;
|
||||
case YAxisType::ImpulseMag: return "Impulse Response (Magnitude)"; break;
|
||||
case YAxisType::Step: return "Step Response"; break;
|
||||
case YAxisType::Impedance: return "Impedance"; break;
|
||||
case YAxisType::Disabled: return "Disabled";
|
||||
case YAxisType::Magnitude: return "Magnitude";
|
||||
case YAxisType::Phase: return "Phase";
|
||||
case YAxisType::VSWR: return "VSWR";
|
||||
case YAxisType::SeriesR: return "Resistance";
|
||||
case YAxisType::Capacitance: return "Capacitance";
|
||||
case YAxisType::Inductance: return "Inductance";
|
||||
case YAxisType::QualityFactor: return "Quality Factor";
|
||||
case YAxisType::ImpulseReal: return "Impulse Response (Real)";
|
||||
case YAxisType::ImpulseMag: return "Impulse Response (Magnitude)";
|
||||
case YAxisType::Step: return "Step Response";
|
||||
case YAxisType::Impedance: return "Impedance";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
@ -827,6 +832,10 @@ bool TraceXYPlot::supported(Trace *t, TraceXYPlot::YAxisType type)
|
||||
case YAxisType::Disabled:
|
||||
return false;
|
||||
case YAxisType::VSWR:
|
||||
case YAxisType::SeriesR:
|
||||
case YAxisType::Capacitance:
|
||||
case YAxisType::Inductance:
|
||||
case YAxisType::QualityFactor:
|
||||
if(!t->isReflection()) {
|
||||
return false;
|
||||
}
|
||||
@ -863,21 +872,31 @@ QPointF TraceXYPlot::traceToCoordinate(Trace *t, unsigned int sample, TraceXYPlo
|
||||
}
|
||||
switch(type) {
|
||||
case YAxisType::Magnitude:
|
||||
ret.setY(Unit::dB(data.y));
|
||||
ret.setY(Util::SparamTodB(data.y));
|
||||
break;
|
||||
case YAxisType::Phase:
|
||||
ret.setY(arg(data.y) * 180.0 / M_PI);
|
||||
ret.setY(Util::SparamToDegree(data.y));
|
||||
break;
|
||||
case YAxisType::VSWR:
|
||||
if(abs(data.y) < 1.0) {
|
||||
ret.setY((1+abs(data.y)) / (1-abs(data.y)));
|
||||
}
|
||||
ret.setY(Util::SparamToVSWR(data.y));
|
||||
break;
|
||||
case YAxisType::SeriesR:
|
||||
ret.setY(Util::SparamToResistance(data.y));
|
||||
break;
|
||||
case YAxisType::Capacitance:
|
||||
ret.setY(Util::SparamToCapacitance(data.y, data.x));
|
||||
break;
|
||||
case YAxisType::Inductance:
|
||||
ret.setY(Util::SparamToInductance(data.y, data.x));
|
||||
break;
|
||||
case YAxisType::QualityFactor:
|
||||
ret.setY(Util::SparamToQualityFactor(data.y));
|
||||
break;
|
||||
case YAxisType::ImpulseReal:
|
||||
ret.setY(real(data.y));
|
||||
break;
|
||||
case YAxisType::ImpulseMag:
|
||||
ret.setY(Unit::dB(data.y));
|
||||
ret.setY(Util::SparamTodB(data.y));
|
||||
break;
|
||||
case YAxisType::Step:
|
||||
ret.setY(t->sample(sample, Trace::SampleType::TimeStep).y.real());
|
||||
@ -885,7 +904,7 @@ QPointF TraceXYPlot::traceToCoordinate(Trace *t, unsigned int sample, TraceXYPlo
|
||||
case YAxisType::Impedance: {
|
||||
double step = t->sample(sample, Trace::SampleType::TimeStep).y.real();
|
||||
if(abs(step) < 1.0) {
|
||||
ret.setY(50 * (1.0+step) / (1.0-step));
|
||||
ret.setY(Util::SparamToImpedance(step).real());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -12,16 +12,21 @@ public:
|
||||
TraceXYPlot(TraceModel &model, QWidget *parent = nullptr);
|
||||
|
||||
enum class YAxisType {
|
||||
Disabled = 0,
|
||||
Disabled,
|
||||
// S parameter options
|
||||
Magnitude = 1,
|
||||
Phase = 2,
|
||||
VSWR = 3,
|
||||
Magnitude,
|
||||
Phase,
|
||||
VSWR,
|
||||
// derived parameter options
|
||||
SeriesR,
|
||||
Capacitance,
|
||||
Inductance,
|
||||
QualityFactor,
|
||||
// TDR options
|
||||
ImpulseReal = 4,
|
||||
ImpulseMag = 5,
|
||||
Step = 6,
|
||||
Impedance = 7,
|
||||
ImpulseReal,
|
||||
ImpulseMag,
|
||||
Step,
|
||||
Impedance,
|
||||
Last,
|
||||
};
|
||||
static const std::set<YAxisType> YAxisTypes;
|
||||
@ -62,9 +67,9 @@ private slots:
|
||||
void updateAxisTicks();
|
||||
private:
|
||||
static constexpr int AxisLabelSize = 10;
|
||||
QString AxisTypeToName(YAxisType type);
|
||||
QString AxisTypeToName(XAxisType type);
|
||||
QString AxisModeToName(XAxisMode mode);
|
||||
static QString AxisTypeToName(YAxisType type);
|
||||
static QString AxisTypeToName(XAxisType type);
|
||||
static QString AxisModeToName(XAxisMode mode);
|
||||
XAxisType XAxisTypeFromName(QString name);
|
||||
YAxisType YAxisTypeFromName(QString name);
|
||||
XAxisMode AxisModeFromName(QString name);
|
||||
|
@ -10,6 +10,13 @@ XYplotAxisDialog::XYplotAxisDialog(TraceXYPlot *plot) :
|
||||
plot(plot)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->Y1type->clear();
|
||||
ui->Y2type->clear();
|
||||
|
||||
for(int i=0;i<(int) TraceXYPlot::YAxisType::Last;i++) {
|
||||
ui->Y1type->addItem(TraceXYPlot::AxisTypeToName((TraceXYPlot::YAxisType) i));
|
||||
ui->Y2type->addItem(TraceXYPlot::AxisTypeToName((TraceXYPlot::YAxisType) i));
|
||||
}
|
||||
|
||||
// Setup GUI connections
|
||||
connect(ui->Y1type, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
@ -69,7 +76,6 @@ XYplotAxisDialog::XYplotAxisDialog(TraceXYPlot *plot) :
|
||||
connect(ui->XType, qOverload<int>(&QComboBox::currentIndexChanged), this, &XYplotAxisDialog::XAxisTypeChanged);
|
||||
|
||||
// Fill initial values
|
||||
// assume same order in YAxisType enum as in ComboBox items
|
||||
ui->Y1type->setCurrentIndex((int) plot->YAxis[0].type);
|
||||
if(plot->YAxis[0].log) {
|
||||
ui->Y1log->setChecked(true);
|
||||
@ -175,6 +181,10 @@ std::set<TraceXYPlot::YAxisType> XYplotAxisDialog::supportedYAxis(TraceXYPlot::X
|
||||
ret.insert(TraceXYPlot::YAxisType::Magnitude);
|
||||
ret.insert(TraceXYPlot::YAxisType::Phase);
|
||||
ret.insert(TraceXYPlot::YAxisType::VSWR);
|
||||
ret.insert(TraceXYPlot::YAxisType::SeriesR);
|
||||
ret.insert(TraceXYPlot::YAxisType::Capacitance);
|
||||
ret.insert(TraceXYPlot::YAxisType::Inductance);
|
||||
ret.insert(TraceXYPlot::YAxisType::QualityFactor);
|
||||
break;
|
||||
case TraceXYPlot::XAxisType::Time:
|
||||
case TraceXYPlot::XAxisType::Distance:
|
||||
|
@ -9,7 +9,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>689</width>
|
||||
<width>773</width>
|
||||
<height>282</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -49,48 +49,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="Y1type">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disabled</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Magnitude</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Phase</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>VSWR</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Impulse Response (real)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Impulse Response (mag)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Step Response</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Impedance</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="Y1type"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@ -219,48 +178,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="Y2type">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disabled</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Magnitude</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Phase</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>VSWR</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Impulse Response (real)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Impulse Response (mag)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Step Response</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Impedance</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="Y2type"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
@ -1,6 +1,10 @@
|
||||
#ifndef UTILH_H
|
||||
#define UTILH_H
|
||||
|
||||
#include <complex>
|
||||
#include <math.h>
|
||||
#include <limits>
|
||||
|
||||
namespace Util {
|
||||
template<typename T> T Scale(T value, T from_low, T from_high, T to_low, T to_high) {
|
||||
value -= from_low;
|
||||
@ -8,6 +12,42 @@ namespace Util {
|
||||
value += to_low;
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline double SparamTodB(double d) {
|
||||
return 20*log10(d);
|
||||
}
|
||||
static inline double SparamTodB(std::complex<double> d) {
|
||||
return SparamTodB(abs(d));
|
||||
}
|
||||
static inline double SparamToDegree(std::complex<double> d) {
|
||||
return (arg(d) * 180.0 / M_PI);
|
||||
}
|
||||
static inline double SparamToVSWR(double d) {
|
||||
if(abs(d) < 1.0) {
|
||||
return (1+abs(d)) / (1-abs(d));
|
||||
} else {
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
}
|
||||
static inline double SparamToVSWR(std::complex<double> d) {
|
||||
return SparamToVSWR(abs(d));
|
||||
}
|
||||
static inline std::complex<double> SparamToImpedance(std::complex<double> d) {
|
||||
return 50.0 * (1.0 + d) / (1.0 - d);
|
||||
}
|
||||
// all these conversions assume series connection of real and imag part
|
||||
static inline double SparamToResistance(std::complex<double> d) {
|
||||
return SparamToImpedance(d).real();
|
||||
}
|
||||
static inline double SparamToCapacitance(std::complex<double> d, double freq) {
|
||||
return -1.0 / (SparamToImpedance(d).imag() * 2.0 * M_PI * freq);
|
||||
}
|
||||
static inline double SparamToInductance(std::complex<double> d, double freq) {
|
||||
return SparamToImpedance(d).imag() / (2.0 * M_PI * freq);
|
||||
}
|
||||
static inline double SparamToQualityFactor(std::complex<double> d) {
|
||||
return abs(d.imag()) / d.real();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // UTILH_H
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <QCheckBox>
|
||||
#include <cmath>
|
||||
#include <QDebug>
|
||||
#include "unit.h"
|
||||
#include "Util/util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -244,7 +244,7 @@ void PortExtension::measurementCompleted(std::vector<Protocol::Datapoint> m)
|
||||
}
|
||||
|
||||
double x = sqrt(p.frequency / m.back().frequency);
|
||||
double y = Unit::dB(reflection);
|
||||
double y = Util::SparamTodB(reflection);
|
||||
att_x.push_back(x);
|
||||
att_y.push_back(y);
|
||||
avg_x += x;
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <cmath>
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include "unit.h"
|
||||
#include "Util/util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -74,7 +74,7 @@ void Touchstone::toFile(string filename, Scale unit, Format format)
|
||||
out << abs(c) << " " << arg(c) / M_PI * 180.0;
|
||||
break;
|
||||
case Format::DBAngle:
|
||||
out << Unit::dB(c) << " " << arg(c) / M_PI * 180.0;
|
||||
out << Util::SparamTodB(c) << " " << arg(c) / M_PI * 180.0;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -87,13 +87,3 @@ double Unit::SIPrefixToFactor(char prefix)
|
||||
default: return 1e0; break;
|
||||
}
|
||||
}
|
||||
|
||||
double Unit::dB(double d)
|
||||
{
|
||||
return 20*log10(d);
|
||||
}
|
||||
|
||||
double Unit::dB(std::complex<double> d)
|
||||
{
|
||||
return dB(abs(d));
|
||||
}
|
||||
|
@ -10,8 +10,6 @@ namespace Unit
|
||||
// prefixed need to be in ascending order (e.g. "m kMG" is okay, whjle "MkG" does not work)
|
||||
QString ToString(double value, QString unit = QString(), QString prefixes = " ", int precision = 6);
|
||||
double SIPrefixToFactor(char prefix);
|
||||
double dB(std::complex<double> d);
|
||||
double dB(double d);
|
||||
};
|
||||
|
||||
#endif // UNIT_H
|
||||
|
Loading…
Reference in New Issue
Block a user