CSV export options extended
This commit is contained in:
parent
000ad0098d
commit
2cf4c5a311
@ -3,6 +3,7 @@
|
|||||||
#include "fftcomplex.h"
|
#include "fftcomplex.h"
|
||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
#include "Marker/marker.h"
|
#include "Marker/marker.h"
|
||||||
|
#include "traceaxis.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -167,54 +168,48 @@ void Trace::fillFromTouchstone(Touchstone &t, unsigned int parameter)
|
|||||||
QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
|
QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
|
||||||
{
|
{
|
||||||
// find correct column
|
// find correct column
|
||||||
unsigned int traceNum = 0;
|
int traceNum = -1;
|
||||||
vector<double> real;
|
|
||||||
vector<double> imag;
|
|
||||||
unsigned int i=1;
|
unsigned int i=1;
|
||||||
QString traceName;
|
QString lastTraceName = "";
|
||||||
bool hasImagValues;
|
bool hasImagValues;
|
||||||
|
std::map<YAxis::Type, int> columnMapping;
|
||||||
for(;i<csv.columns();i++) {
|
for(;i<csv.columns();i++) {
|
||||||
traceName = QString();
|
auto header = csv.getHeader(i);
|
||||||
hasImagValues = false;
|
auto splitIndex = header.lastIndexOf("_");
|
||||||
// check column names
|
if(splitIndex == -1) {
|
||||||
if(i < csv.columns() - 1) {
|
// no "_", not following naming format of CSV export, skip
|
||||||
// not the last column, check if this and next header implies real/imag values
|
continue;
|
||||||
auto name_real = csv.getHeader(i);
|
|
||||||
auto name_imag = csv.getHeader(i + 1);
|
|
||||||
if(name_real.endsWith("_real") && name_imag.endsWith("_imag")) {
|
|
||||||
// check if headers have the same beginning
|
|
||||||
name_real.chop(5);
|
|
||||||
name_imag.chop(5);
|
|
||||||
if(name_real == name_imag) {
|
|
||||||
hasImagValues = true;
|
|
||||||
traceName = name_real;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(!hasImagValues) {
|
auto traceName = header.left(splitIndex);
|
||||||
traceName = csv.getHeader(i);
|
auto yaxistype = header.right(header.size() - splitIndex - 1);
|
||||||
|
if(traceName != lastTraceName) {
|
||||||
|
traceNum++;
|
||||||
|
if(traceNum > parameter) {
|
||||||
|
// got all columns for the trace we are interested in
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lastTraceName = traceName;
|
||||||
}
|
}
|
||||||
if(traceNum == parameter) {
|
if(traceNum == parameter) {
|
||||||
// this is the desired trace
|
// this is the trace we are looking for, get axistype and add to mapping
|
||||||
break;
|
|
||||||
} else {
|
// handle legacy column naming, translate to new naming
|
||||||
traceNum++;
|
if(yaxistype == "real") {
|
||||||
}
|
yaxistype = YAxis::TypeToName(YAxis::Type::Real);
|
||||||
if(hasImagValues) {
|
} else if(yaxistype == "imag") {
|
||||||
// next column already used by this trace, skip
|
yaxistype = YAxis::TypeToName(YAxis::Type::Imaginary);
|
||||||
i++;
|
}
|
||||||
|
|
||||||
|
columnMapping[YAxis::TypeFromName(yaxistype)] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(i >= csv.columns()) {
|
if(traceNum < parameter) {
|
||||||
throw runtime_error("Not enough traces in CSV file");
|
throw runtime_error("Not enough traces in CSV file");
|
||||||
}
|
}
|
||||||
real = csv.getColumn(i);
|
if(columnMapping.size() == 0) {
|
||||||
if(hasImagValues) {
|
throw runtime_error("No data for trace in CSV file");
|
||||||
imag = csv.getColumn(i + 1);
|
|
||||||
} else {
|
|
||||||
imag.resize(real.size());
|
|
||||||
fill(imag.begin(), imag.end(), 0.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
fileParameter = parameter;
|
fileParameter = parameter;
|
||||||
filename = csv.getFilename();
|
filename = csv.getFilename();
|
||||||
@ -227,16 +222,20 @@ QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
|
|||||||
domain = DataType::Frequency;
|
domain = DataType::Frequency;
|
||||||
}
|
}
|
||||||
for(unsigned int i=0;i<xColumn.size();i++) {
|
for(unsigned int i=0;i<xColumn.size();i++) {
|
||||||
|
std::map<YAxis::Type, double> data;
|
||||||
|
for(auto map : columnMapping) {
|
||||||
|
data[map.first] = csv.getColumn(map.second)[i];
|
||||||
|
}
|
||||||
Data d;
|
Data d;
|
||||||
d.x = xColumn[i];
|
d.x = xColumn[i];
|
||||||
d.y = complex<double>(real[i], imag[i]);
|
d.y = YAxis::reconstructValueFromYAxisType(data);
|
||||||
addData(d, domain);
|
addData(d, domain);
|
||||||
}
|
}
|
||||||
reflection = false;
|
reflection = false;
|
||||||
createdFromFile = true;
|
createdFromFile = true;
|
||||||
emit typeChanged(this);
|
emit typeChanged(this);
|
||||||
emit outputSamplesChanged(0, data.size());
|
emit outputSamplesChanged(0, data.size());
|
||||||
return traceName;
|
return lastTraceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Trace::fillFromDatapoints(Trace &S11, Trace &S12, Trace &S21, Trace &S22, const std::vector<VNAData> &data)
|
void Trace::fillFromDatapoints(Trace &S11, Trace &S12, Trace &S21, Trace &S22, const std::vector<VNAData> &data)
|
||||||
|
@ -317,6 +317,95 @@ YAxis::Type YAxis::getType() const
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<YAxis::Type> YAxis::getSupported(XAxis::Type type, TraceModel::DataSource source)
|
||||||
|
{
|
||||||
|
std::set<YAxis::Type> ret = {YAxis::Type::Disabled};
|
||||||
|
if(source == TraceModel::DataSource::VNA) {
|
||||||
|
switch(type) {
|
||||||
|
case XAxis::Type::Frequency:
|
||||||
|
case XAxis::Type::Power:
|
||||||
|
ret.insert(YAxis::Type::Magnitude);
|
||||||
|
ret.insert(YAxis::Type::MagnitudeLinear);
|
||||||
|
ret.insert(YAxis::Type::Phase);
|
||||||
|
ret.insert(YAxis::Type::UnwrappedPhase);
|
||||||
|
ret.insert(YAxis::Type::VSWR);
|
||||||
|
ret.insert(YAxis::Type::Real);
|
||||||
|
ret.insert(YAxis::Type::Imaginary);
|
||||||
|
ret.insert(YAxis::Type::SeriesR);
|
||||||
|
ret.insert(YAxis::Type::Reactance);
|
||||||
|
ret.insert(YAxis::Type::Capacitance);
|
||||||
|
ret.insert(YAxis::Type::Inductance);
|
||||||
|
ret.insert(YAxis::Type::QualityFactor);
|
||||||
|
ret.insert(YAxis::Type::GroupDelay);
|
||||||
|
break;
|
||||||
|
case XAxis::Type::Time:
|
||||||
|
case XAxis::Type::Distance:
|
||||||
|
ret.insert(YAxis::Type::ImpulseReal);
|
||||||
|
ret.insert(YAxis::Type::ImpulseMag);
|
||||||
|
ret.insert(YAxis::Type::Step);
|
||||||
|
ret.insert(YAxis::Type::Impedance);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if(source == TraceModel::DataSource::SA) {
|
||||||
|
switch(type) {
|
||||||
|
case XAxis::Type::Frequency:
|
||||||
|
ret.insert(YAxis::Type::Magnitude);
|
||||||
|
ret.insert(YAxis::Type::MagnitudedBuV);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::complex<double> YAxis::reconstructValueFromYAxisType(std::map<YAxis::Type, double> yaxistypes)
|
||||||
|
{
|
||||||
|
std::complex<double> ret = std::numeric_limits<std::complex<double>>::quiet_NaN();
|
||||||
|
if(yaxistypes.count(Type::Real)) {
|
||||||
|
ret.real(yaxistypes[Type::Real]);
|
||||||
|
if(yaxistypes.count(Type::Imaginary)) {
|
||||||
|
ret.imag(yaxistypes[Type::Imaginary]);
|
||||||
|
} else {
|
||||||
|
ret.imag(0.0);
|
||||||
|
}
|
||||||
|
} else if(yaxistypes.count(Type::Magnitude) || yaxistypes.count(Type::MagnitudedBuV) || yaxistypes.count(Type::MagnitudeLinear)) {
|
||||||
|
double maglin, phase;
|
||||||
|
if(yaxistypes.count(Type::MagnitudeLinear)) {
|
||||||
|
maglin = yaxistypes[Type::MagnitudeLinear];
|
||||||
|
} else if(yaxistypes.count(Type::Magnitude)) {
|
||||||
|
maglin = Util::dBToMagnitude(yaxistypes[Type::Magnitude]);
|
||||||
|
} else {
|
||||||
|
auto dBm = Util::dBuVTodBm(yaxistypes[Type::MagnitudedBuV]);
|
||||||
|
maglin = Util::dBToMagnitude(dBm);
|
||||||
|
}
|
||||||
|
if(yaxistypes.count(Type::Phase)) {
|
||||||
|
phase = yaxistypes[Type::Phase];
|
||||||
|
} else {
|
||||||
|
phase = 0.0;
|
||||||
|
}
|
||||||
|
ret = polar<double>(maglin, phase / 180.0 * M_PI);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XAxis::isSupported(XAxis::Type type, TraceModel::DataSource source)
|
||||||
|
{
|
||||||
|
if(source == TraceModel::DataSource::VNA) {
|
||||||
|
// all X axis types are supported
|
||||||
|
return true;
|
||||||
|
} else if(source == TraceModel::DataSource::SA) {
|
||||||
|
if (type == XAxis::Type::Frequency) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Axis::updateTicks()
|
void Axis::updateTicks()
|
||||||
{
|
{
|
||||||
if(log) {
|
if(log) {
|
||||||
|
@ -29,6 +29,32 @@ protected:
|
|||||||
std::vector<double> ticks;
|
std::vector<double> ticks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class XAxis : public Axis {
|
||||||
|
public:
|
||||||
|
enum class Type {
|
||||||
|
Frequency,
|
||||||
|
Time,
|
||||||
|
Distance,
|
||||||
|
Power,
|
||||||
|
Last,
|
||||||
|
};
|
||||||
|
XAxis();
|
||||||
|
double sampleToCoordinate(Trace::Data data, Trace *t = nullptr, unsigned int sample = 0) override;
|
||||||
|
void set(Type type, bool log, bool autorange, double min, double max, double div);
|
||||||
|
static QString TypeToName(Type type);
|
||||||
|
static Type TypeFromName(QString name);
|
||||||
|
static QString Unit(Type type);
|
||||||
|
QString TypeToName();
|
||||||
|
QString Unit();
|
||||||
|
|
||||||
|
Type getType() const;
|
||||||
|
|
||||||
|
static bool isSupported(XAxis::Type type, TraceModel::DataSource source);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type type;
|
||||||
|
};
|
||||||
|
|
||||||
class YAxis : public Axis {
|
class YAxis : public Axis {
|
||||||
public:
|
public:
|
||||||
enum class Type {
|
enum class Type {
|
||||||
@ -58,6 +84,7 @@ public:
|
|||||||
};
|
};
|
||||||
YAxis();
|
YAxis();
|
||||||
double sampleToCoordinate(Trace::Data data, Trace *t = nullptr, unsigned int sample = 0) override;
|
double sampleToCoordinate(Trace::Data data, Trace *t = nullptr, unsigned int sample = 0) override;
|
||||||
|
|
||||||
void set(Type type, bool log, bool autorange, double min, double max, double div);
|
void set(Type type, bool log, bool autorange, double min, double max, double div);
|
||||||
static QString TypeToName(Type type);
|
static QString TypeToName(Type type);
|
||||||
static Type TypeFromName(QString name);
|
static Type TypeFromName(QString name);
|
||||||
@ -69,29 +96,8 @@ public:
|
|||||||
|
|
||||||
Type getType() const;
|
Type getType() const;
|
||||||
|
|
||||||
private:
|
static std::set<YAxis::Type> getSupported(XAxis::Type type, TraceModel::DataSource source);
|
||||||
Type type;
|
static std::complex<double> reconstructValueFromYAxisType(std::map<Type, double> yaxistypes);
|
||||||
};
|
|
||||||
|
|
||||||
class XAxis : public Axis {
|
|
||||||
public:
|
|
||||||
enum class Type {
|
|
||||||
Frequency,
|
|
||||||
Time,
|
|
||||||
Distance,
|
|
||||||
Power,
|
|
||||||
Last,
|
|
||||||
};
|
|
||||||
XAxis();
|
|
||||||
double sampleToCoordinate(Trace::Data data, Trace *t = nullptr, unsigned int sample = 0) override;
|
|
||||||
void set(Type type, bool log, bool autorange, double min, double max, double div);
|
|
||||||
static QString TypeToName(Type type);
|
|
||||||
static Type TypeFromName(QString name);
|
|
||||||
static QString Unit(Type type);
|
|
||||||
QString TypeToName();
|
|
||||||
QString Unit();
|
|
||||||
|
|
||||||
Type getType() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type type;
|
Type type;
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include "ui_tracecsvexport.h"
|
#include "ui_tracecsvexport.h"
|
||||||
#include "csv.h"
|
#include "csv.h"
|
||||||
|
|
||||||
|
#include "traceaxis.h"
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
@ -19,6 +21,35 @@ TraceCSVExport::TraceCSVExport(TraceModel &traceModel, QWidget *parent) :
|
|||||||
ui->listView->setModel(&model);
|
ui->listView->setModel(&model);
|
||||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||||
connect(&model, &TraceCSVModel::selectionChanged, ui->buttonBox->button(QDialogButtonBox::Ok), &QPushButton::setEnabled);
|
connect(&model, &TraceCSVModel::selectionChanged, ui->buttonBox->button(QDialogButtonBox::Ok), &QPushButton::setEnabled);
|
||||||
|
connect(&model, &TraceCSVModel::selectionChanged, [&](){
|
||||||
|
auto traces = model.tracesToExport();
|
||||||
|
if(traces.size() == 0) {
|
||||||
|
ui->listColumns->clear();
|
||||||
|
} else if(ui->listColumns->count() == 0) {
|
||||||
|
// first trace has bee selected, fill column selection
|
||||||
|
auto t = traces.front();
|
||||||
|
auto domain = t->outputType();
|
||||||
|
auto Xaxis = XAxis::Type::Last;
|
||||||
|
switch(domain) {
|
||||||
|
case Trace::DataType::Frequency: Xaxis = XAxis::Type::Frequency; break;
|
||||||
|
case Trace::DataType::Power: Xaxis = XAxis::Type::Power; break;
|
||||||
|
case Trace::DataType::Time: Xaxis = XAxis::Type::Time; break;
|
||||||
|
}
|
||||||
|
if(Xaxis == XAxis::Type::Last) {
|
||||||
|
// invalid axis selection
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(auto ytype : YAxis::getSupported(Xaxis, traceModel.getSource())) {
|
||||||
|
if(ytype != YAxis::Type::Disabled) {
|
||||||
|
auto item = new QListWidgetItem(YAxis::TypeToName(ytype), ui->listColumns);
|
||||||
|
item->setCheckState(Qt::Unchecked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// first fill of selection, nothing selected yet, disable OK button
|
||||||
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(ui->listColumns, &QListWidget::itemChanged, this, &TraceCSVExport::columnSelectionChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceCSVExport::~TraceCSVExport()
|
TraceCSVExport::~TraceCSVExport()
|
||||||
@ -26,6 +57,12 @@ TraceCSVExport::~TraceCSVExport()
|
|||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TraceCSVExport::columnSelectionChanged()
|
||||||
|
{
|
||||||
|
auto types = getSelectedYAxisTypes();
|
||||||
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(types.size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
void TraceCSVExport::on_buttonBox_accepted()
|
void TraceCSVExport::on_buttonBox_accepted()
|
||||||
{
|
{
|
||||||
auto traces = model.tracesToExport();
|
auto traces = model.tracesToExport();
|
||||||
@ -52,29 +89,35 @@ void TraceCSVExport::on_buttonBox_accepted()
|
|||||||
}
|
}
|
||||||
csv.addColumn(Xname, X);
|
csv.addColumn(Xname, X);
|
||||||
// add the trace data
|
// add the trace data
|
||||||
for(auto t : traces) {
|
for(auto trace : traces) {
|
||||||
vector<double> real;
|
for(auto ytype : getSelectedYAxisTypes()) {
|
||||||
vector<double> imag;
|
auto axis = YAxis();
|
||||||
auto samples = t->numSamples();
|
axis.set(ytype, false, false, 0, 1, 1);
|
||||||
for(unsigned int i=0;i<samples;i++) {
|
auto samples = trace->numSamples();
|
||||||
real.push_back(t->sample(i).y.real());
|
vector<double> values;
|
||||||
imag.push_back(t->sample(i).y.imag());
|
for(unsigned int i=0;i<samples;i++) {
|
||||||
}
|
values.push_back(axis.sampleToCoordinate(trace->sample(i), trace, i));
|
||||||
// check if this is a real or complex trace
|
}
|
||||||
bool allZeros = std::all_of(imag.begin(), imag.end(), [](double i) { return i==0.0; });
|
csv.addColumn(trace->name()+"_"+axis.TypeToName(), values);
|
||||||
if(allZeros) {
|
|
||||||
// only real values, one column is enough
|
|
||||||
csv.addColumn(t->name(), real);
|
|
||||||
} else {
|
|
||||||
// complex values, need two columns
|
|
||||||
csv.addColumn(t->name()+"_real", real);
|
|
||||||
csv.addColumn(t->name()+"_imag", imag);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
csv.toFile(filename);
|
csv.toFile(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<YAxis::Type> TraceCSVExport::getSelectedYAxisTypes()
|
||||||
|
{
|
||||||
|
std::vector<YAxis::Type> ret;
|
||||||
|
for(unsigned int i=0;i<ui->listColumns->count();i++) {
|
||||||
|
auto item = ui->listColumns->item(i);
|
||||||
|
if(item->checkState() == Qt::Checked) {
|
||||||
|
auto type = YAxis::TypeFromName(item->text());
|
||||||
|
ret.push_back(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
TraceCSVModel::TraceCSVModel(std::vector<Trace *> traces, QObject *parent)
|
TraceCSVModel::TraceCSVModel(std::vector<Trace *> traces, QObject *parent)
|
||||||
: QAbstractListModel(parent)
|
: QAbstractListModel(parent)
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define TRACECSVEXPORT_H
|
#define TRACECSVEXPORT_H
|
||||||
|
|
||||||
#include "tracemodel.h"
|
#include "tracemodel.h"
|
||||||
|
#include "traceaxis.h"
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
@ -44,9 +45,11 @@ public:
|
|||||||
~TraceCSVExport();
|
~TraceCSVExport();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void columnSelectionChanged();
|
||||||
void on_buttonBox_accepted();
|
void on_buttonBox_accepted();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::vector<YAxis::Type> getSelectedYAxisTypes();
|
||||||
Ui::TraceCSVExport *ui;
|
Ui::TraceCSVExport *ui;
|
||||||
TraceCSVModel model;
|
TraceCSVModel model;
|
||||||
};
|
};
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>286</width>
|
<width>469</width>
|
||||||
<height>322</height>
|
<height>330</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -19,13 +19,38 @@
|
|||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QListView" name="listView">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<property name="selectionBehavior">
|
<item>
|
||||||
<enum>QAbstractItemView::SelectRows</enum>
|
<widget class="QGroupBox" name="groupBox">
|
||||||
</property>
|
<property name="title">
|
||||||
</widget>
|
<string>Traces</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QListView" name="listView">
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Columns</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="listColumns"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "xyplotaxisdialog.h"
|
#include "xyplotaxisdialog.h"
|
||||||
|
|
||||||
#include "ui_xyplotaxisdialog.h"
|
#include "ui_xyplotaxisdialog.h"
|
||||||
|
#include "traceaxis.h"
|
||||||
|
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
|
|
||||||
@ -223,61 +224,10 @@ void XYplotAxisDialog::XAxisTypeChanged(int XAxisIndex)
|
|||||||
|
|
||||||
std::set<YAxis::Type> XYplotAxisDialog::supportedYAxis(XAxis::Type type)
|
std::set<YAxis::Type> XYplotAxisDialog::supportedYAxis(XAxis::Type type)
|
||||||
{
|
{
|
||||||
set<YAxis::Type> ret = {YAxis::Type::Disabled};
|
return YAxis::getSupported(type, plot->getModel().getSource());
|
||||||
auto source = plot->getModel().getSource();
|
|
||||||
if(source == TraceModel::DataSource::VNA) {
|
|
||||||
switch(type) {
|
|
||||||
case XAxis::Type::Frequency:
|
|
||||||
case XAxis::Type::Power:
|
|
||||||
ret.insert(YAxis::Type::Magnitude);
|
|
||||||
ret.insert(YAxis::Type::MagnitudeLinear);
|
|
||||||
ret.insert(YAxis::Type::Phase);
|
|
||||||
ret.insert(YAxis::Type::UnwrappedPhase);
|
|
||||||
ret.insert(YAxis::Type::VSWR);
|
|
||||||
ret.insert(YAxis::Type::Real);
|
|
||||||
ret.insert(YAxis::Type::Imaginary);
|
|
||||||
ret.insert(YAxis::Type::SeriesR);
|
|
||||||
ret.insert(YAxis::Type::Reactance);
|
|
||||||
ret.insert(YAxis::Type::Capacitance);
|
|
||||||
ret.insert(YAxis::Type::Inductance);
|
|
||||||
ret.insert(YAxis::Type::QualityFactor);
|
|
||||||
ret.insert(YAxis::Type::GroupDelay);
|
|
||||||
break;
|
|
||||||
case XAxis::Type::Time:
|
|
||||||
case XAxis::Type::Distance:
|
|
||||||
ret.insert(YAxis::Type::ImpulseReal);
|
|
||||||
ret.insert(YAxis::Type::ImpulseMag);
|
|
||||||
ret.insert(YAxis::Type::Step);
|
|
||||||
ret.insert(YAxis::Type::Impedance);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if(source == TraceModel::DataSource::SA) {
|
|
||||||
switch(type) {
|
|
||||||
case XAxis::Type::Frequency:
|
|
||||||
ret.insert(YAxis::Type::Magnitude);
|
|
||||||
ret.insert(YAxis::Type::MagnitudedBuV);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XYplotAxisDialog::isSupported(XAxis::Type type)
|
bool XYplotAxisDialog::isSupported(XAxis::Type type)
|
||||||
{
|
{
|
||||||
auto source = plot->getModel().getSource();
|
return XAxis::isSupported(type, plot->getModel().getSource());
|
||||||
if(source == TraceModel::DataSource::VNA) {
|
|
||||||
// all X axis types are supported
|
|
||||||
return true;
|
|
||||||
} else if(source == TraceModel::DataSource::SA) {
|
|
||||||
if (type == XAxis::Type::Frequency) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
@ -72,3 +72,10 @@ double Util::dBmTodBuV(double dBm)
|
|||||||
double dBdiff = 10*log10(uVpower*1000);
|
double dBdiff = 10*log10(uVpower*1000);
|
||||||
return dBm - dBdiff;
|
return dBm - dBdiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Util::dBuVTodBm(double dBuV)
|
||||||
|
{
|
||||||
|
double uVpower = 0.000001*0.000001/50.0;
|
||||||
|
double dBdiff = 10*log10(uVpower*1000);
|
||||||
|
return dBuV + dBdiff;
|
||||||
|
}
|
||||||
|
@ -31,7 +31,11 @@ namespace Util {
|
|||||||
static inline double SparamTodB(std::complex<double> d) {
|
static inline double SparamTodB(std::complex<double> d) {
|
||||||
return SparamTodB(abs(d));
|
return SparamTodB(abs(d));
|
||||||
}
|
}
|
||||||
|
static inline double dBToMagnitude(double dB) {
|
||||||
|
return pow(10, dB / 20);
|
||||||
|
}
|
||||||
double dBmTodBuV(double dBm);
|
double dBmTodBuV(double dBm);
|
||||||
|
double dBuVTodBm(double dBuV);
|
||||||
static inline double SparamToDegree(std::complex<double> d) {
|
static inline double SparamToDegree(std::complex<double> d) {
|
||||||
return (arg(d) * 180.0 / M_PI);
|
return (arg(d) * 180.0 / M_PI);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user