Added mixed mode conversion dialog

This commit is contained in:
Jan Käberich 2022-11-09 12:33:14 +01:00
parent 1a1c9fd345
commit 7d7bd3a44c
16 changed files with 594 additions and 530993 deletions

View File

@ -0,0 +1,218 @@
#include "tracesetselector.h"
#include <QGridLayout>
#include <QLabel>
TraceSetSelector::TraceSetSelector(QWidget *parent) :
QWidget(parent),
model(nullptr)
{
points = 0;
ports = 0;
lowerFreq = upperFreq = 0;
referenceImpedance = 50.0;
freqsSet = false;
partialSelectionAllowed = false;
setLayout(new QGridLayout);
setPorts(2);
}
TraceSetSelector::~TraceSetSelector()
{
blockSignals(true);
// this will free all created widgets
setPorts(0);
blockSignals(false);
}
unsigned int TraceSetSelector::getPorts() const
{
return ports;
}
void TraceSetSelector::setPorts(unsigned int newPorts)
{
if(!model) {
return;
}
QGridLayout *layout = static_cast<QGridLayout*>(this->layout());
if(newPorts != ports) {
ports = newPorts;
// remove the previous widgets
QLayoutItem *child;
while ((child = layout->takeAt(0)) != 0) {
delete child->widget();
delete child;
}
cTraces.clear();
for(unsigned int i=0;i<ports;i++) {
cTraces.push_back(std::vector<QComboBox*>());
for(unsigned int j=0;j<ports;j++) {
auto l = new QLabel("S"+QString::number(i+1)+QString::number(j+1)+":");
auto c = new QComboBox();
cTraces[i].push_back(c);
connect(c, qOverload<int>(&QComboBox::currentIndexChanged), [=](int) {
selectionChanged(c);
});
layout->addWidget(l, i, j*2);
layout->addWidget(c, i, j*2 + 1);
}
}
}
auto availableTraces = model->getTraces();
for(unsigned int i=0;i<ports;i++) {
for(unsigned int j=0;j<ports;j++) {
auto c = cTraces[i][j];
c->blockSignals(true);
c->clear();
// create possible trace selections
c->addItem("None");
for(auto t : availableTraces) {
if(t->getDataType() != Trace::DataType::Frequency) {
// can only add frequency traces
continue;
}
if(i == j && !t->isReflection()) {
// can not add through measurement at reflection port
continue;
} else if(i != j && t->isReflection()) {
// can not add reflection measurement at through port
continue;
}
c->addItem(t->name(), QVariant::fromValue<Trace*>(t));
}
c->blockSignals(false);
}
}
emit selectionChanged();
}
bool TraceSetSelector::setTrace(unsigned int destPort, unsigned int srcPort, Trace *t)
{
if(destPort < 1 || destPort > ports || srcPort < 1 || srcPort > ports) {
// invalid port selection
return false;
}
auto c = cTraces[destPort-1][srcPort-1];
// find required trace
for(unsigned int i=1;i<(unsigned int) c->count();i++) {
if(qvariant_cast<Trace*>(c->itemData(i)) == t) {
c->setCurrentIndex(i);
return true;
}
}
// requested trace not found, unable to set
return false;
}
Trace *TraceSetSelector::getTrace(unsigned int destPort, unsigned int srcPort)
{
if(destPort < 1 || destPort > ports || srcPort < 1 || srcPort > ports) {
// invalid port selection
return nullptr;
}
auto c = cTraces[destPort-1][srcPort-1];
if(c->currentIndex() == 0) {
// no trace selected
return nullptr;
} else {
return qvariant_cast<Trace*>(c->itemData(c->currentIndex()));
}
}
bool TraceSetSelector::selectionValid()
{
for(unsigned int i=1;i<=ports;i++) {
for(unsigned int j=1;j<=ports;j++) {
auto t = getTrace(i, j);
if(!t && !partialSelectionAllowed) {
// at least one trace is missing
return false;
}
if(t && partialSelectionAllowed) {
// at least one trace is present
return true;
}
}
}
// if we get here, either:
// - all traces are valid and partial selection is not allowed -> whole selection valid
// or:
// - all traces are invalid and partial selection is allowed -> whole selection invalid
return !partialSelectionAllowed;
}
void TraceSetSelector::selectionChanged(QComboBox *c)
{
if(c->currentIndex() != 0 && !freqsSet) {
// the first trace has been selected, extract frequency info
Trace *t = qvariant_cast<Trace*>(c->itemData(c->currentIndex()));
points = t->size();
referenceImpedance = t->getReferenceImpedance();
if(points > 0) {
lowerFreq = t->minX();
upperFreq = t->maxX();
}
freqsSet = true;
// remove all trace options with incompatible frequencies
for(auto v1 : cTraces) {
for(auto c : v1) {
for(int i=1;i<c->count();i++) {
Trace *t = qvariant_cast<Trace*>(c->itemData(i));
if(t->getReferenceImpedance() != referenceImpedance || t->size() != points || (points > 0 && (t->minX() != lowerFreq || t->maxX() != upperFreq))) {
// this trace is not available anymore
c->removeItem(i);
// decrement to check the next index in the next loop iteration
i--;
}
}
}
}
} else if(c->currentIndex() == 0 && freqsSet) {
// Check if all trace selections are set for none
for(auto v1 : cTraces) {
for(auto c : v1) {
if(c->currentIndex() != 0) {
// some trace is still selected, abort
emit selectionChanged();
return;
}
}
}
// all traces set for none
freqsSet = false;
setPorts(ports);
}
emit selectionChanged();
}
double TraceSetSelector::getReferenceImpedance() const
{
return referenceImpedance;
}
double TraceSetSelector::getUpperFreq() const
{
return upperFreq;
}
double TraceSetSelector::getLowerFreq() const
{
return lowerFreq;
}
unsigned int TraceSetSelector::getPoints() const
{
return points;
}
void TraceSetSelector::setModel(TraceModel *newModel)
{
model = newModel;
}
void TraceSetSelector::setPartialSelectionAllowed(bool newPartialSelectionAllowed)
{
partialSelectionAllowed = newPartialSelectionAllowed;
}

View File

@ -0,0 +1,57 @@
#ifndef TRACESETSELECTOR_H
#define TRACESETSELECTOR_H
#include "Traces/tracemodel.h"
#include <QWidget>
#include <QComboBox>
namespace Ui {
class TraceSetSelector;
}
class TraceSetSelector : public QWidget
{
Q_OBJECT
public:
explicit TraceSetSelector(QWidget *parent = nullptr);
~TraceSetSelector();
unsigned int getPorts() const;
void setPorts(unsigned int newPorts);
bool setTrace(unsigned int destPort, unsigned int srcPort, Trace *t);
Trace *getTrace(unsigned int destPort, unsigned int srcPort);
bool selectionValid();
void setPartialSelectionAllowed(bool newPartialSelectionAllowed);
void setModel(TraceModel *newModel);
unsigned int getPoints() const;
double getLowerFreq() const;
double getUpperFreq() const;
double getReferenceImpedance() const;
signals:
void selectionChanged();
private:
void selectionChanged(QComboBox *c);
Ui::TraceSetSelector *ui;
TraceModel *model;
unsigned int ports;
std::vector<std::vector<QComboBox*>> cTraces;
unsigned int points;
double lowerFreq, upperFreq;
double referenceImpedance;
bool freqsSet;
bool partialSelectionAllowed;
};
#endif // TRACESETSELECTOR_H

View File

@ -21,6 +21,7 @@ HEADERS += \
CustomWidgets/tilewidget.h \
CustomWidgets/toggleswitch.h \
CustomWidgets/touchstoneimport.h \
CustomWidgets/tracesetselector.h \
Device/compounddevice.h \
Device/compounddeviceeditdialog.h \
Device/device.h \
@ -36,6 +37,7 @@ HEADERS += \
SpectrumAnalyzer/tracewidgetsa.h \
Tools/eseries.h \
Tools/impedancematchdialog.h \
Tools/mixedmodeconversion.h \
Tools/parameters.h \
Traces/Marker/marker.h \
Traces/Marker/markergroup.h \
@ -167,6 +169,7 @@ SOURCES += \
CustomWidgets/tilewidget.cpp \
CustomWidgets/toggleswitch.cpp \
CustomWidgets/touchstoneimport.cpp \
CustomWidgets/tracesetselector.cpp \
Device/compounddevice.cpp \
Device/compounddeviceeditdialog.cpp \
Device/device.cpp \
@ -182,6 +185,7 @@ SOURCES += \
SpectrumAnalyzer/tracewidgetsa.cpp \
Tools/eseries.cpp \
Tools/impedancematchdialog.cpp \
Tools/mixedmodeconversion.cpp \
Tools/parameters.cpp \
Traces/Marker/marker.cpp \
Traces/Marker/markergroup.cpp \
@ -311,6 +315,7 @@ FORMS += \
Device/manualcontroldialog.ui \
Generator/signalgenwidget.ui \
Tools/impedancematchdialog.ui \
Tools/mixedmodeconversion.ui \
Traces/Marker/markerwidget.ui \
Traces/Math/dftdialog.ui \
Traces/Math/dftexplanationwidget.ui \

View File

@ -0,0 +1,146 @@
#include "mixedmodeconversion.h"
#include "ui_mixedmodeconversion.h"
#include <QPushButton>
MixedModeConversion::MixedModeConversion(TraceModel &m, QWidget *parent) :
QDialog(parent),
ui(new Ui::MixedModeConversion)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
ui->selector->setModel(&m);
ui->selector->setPorts(4);
connect(ui->selector, qOverload<>(&TraceSetSelector::selectionChanged), this, &MixedModeConversion::selectionChanged);
connect(ui->prefix, &QLineEdit::textChanged, this, &MixedModeConversion::selectionChanged);
connect(ui->buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, [=](){
emit tracesCreated(traces);
accept();
});
connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &QDialog::reject);
selectionChanged();
}
MixedModeConversion::~MixedModeConversion()
{
delete ui;
}
void MixedModeConversion::selectionChanged()
{
for(auto t : traces) {
delete t;
}
traces.clear();
class Source {
public:
Source(TraceSetSelector *sel, QString name) {
this->name = name;
t = sel->getTrace(name.mid(1, 1).toUInt(), name.mid(2, 1).toUInt());
}
QString name;
Trace *t;
};
std::vector<Source> sources = {
Source(ui->selector, "S11"),
Source(ui->selector, "S12"),
Source(ui->selector, "S13"),
Source(ui->selector, "S14"),
Source(ui->selector, "S21"),
Source(ui->selector, "S22"),
Source(ui->selector, "S23"),
Source(ui->selector, "S24"),
Source(ui->selector, "S31"),
Source(ui->selector, "S32"),
Source(ui->selector, "S33"),
Source(ui->selector, "S34"),
Source(ui->selector, "S41"),
Source(ui->selector, "S42"),
Source(ui->selector, "S43"),
Source(ui->selector, "S44"),
};
class Destination {
public:
Destination(std::vector<Source> sources, QString name, QString formula)
{
this->name = name;
t = new Trace(name);
t->fromMath();
t->setMathFormula(formula);
// is a reflection trace if the last two chars in the name are the same
t->setReflection(name[name.size()-1] == name[name.size()-2]);
// add math sources
int index = 0;
while((index = formula.indexOf("S", index)) != -1) {
QString source = formula.mid(index, 3);
// find the source trace
bool sourceSet = false;
for(auto s : sources) {
if(!s.t) {
// not set, unable to use this source
continue;
}
if(s.name == source) {
if(t->addMathSource(s.t, s.name)) {
// added as source, exit loop
sourceSet = true;
break;
} else {
// failed to add
delete t;
t = nullptr;
return;
}
}
}
if(!sourceSet) {
// can't find this source
delete t;
t = nullptr;
return;
}
index++;
}
}
QString name;
Trace *t;
};
auto prefix = ui->prefix->text();
std::vector<Destination> destinations = {
Destination(sources, prefix+"SDD11", "0.5*(S11-S13-S31+S33)"),
Destination(sources, prefix+"SDD12", "0.5*(S12-S14-S32+S34)"),
Destination(sources, prefix+"SDD21", "0.5*(S21-S23-S41+S43)"),
Destination(sources, prefix+"SDD22", "0.5*(S22-S24-S42+S44)"),
Destination(sources, prefix+"SDC11", "0.5*(S11+S13-S31+S33)"),
Destination(sources, prefix+"SDC12", "0.5*(S12+S14-S32+S34)"),
Destination(sources, prefix+"SDC21", "0.5*(S21+S23-S41+S43)"),
Destination(sources, prefix+"SDC22", "0.5*(S22+S24-S42+S44)"),
Destination(sources, prefix+"SCD11", "0.5*(S11-S13+S31-S33)"),
Destination(sources, prefix+"SCD12", "0.5*(S12-S14+S32-S34)"),
Destination(sources, prefix+"SCD21", "0.5*(S21-S23+S41-S43)"),
Destination(sources, prefix+"SCD22", "0.5*(S22-S24+S42-S44)"),
Destination(sources, prefix+"SCC11", "0.5*(S11+S13+S31+S33)"),
Destination(sources, prefix+"SCC12", "0.5*(S12+S14+S32+S34)"),
Destination(sources, prefix+"SCC21", "0.5*(S21+S23+S41+S43)"),
Destination(sources, prefix+"SCC22", "0.5*(S22+S24+S42+S44)"),
};
ui->list->clear();
for(auto d : destinations) {
if(d.t) {
traces.push_back(d.t);
ui->list->addItem(d.name);
}
}
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(traces.size() > 0);
}

View File

@ -0,0 +1,30 @@
#ifndef MIXEDMODECONVERSION_H
#define MIXEDMODECONVERSION_H
#include "Traces/tracemodel.h"
#include <QDialog>
namespace Ui {
class MixedModeConversion;
}
class MixedModeConversion : public QDialog
{
Q_OBJECT
public:
explicit MixedModeConversion(TraceModel &m, QWidget *parent = nullptr);
~MixedModeConversion();
signals:
void tracesCreated(std::vector<Trace*> traces);
private slots:
void selectionChanged();
private:
Ui::MixedModeConversion *ui;
std::vector<Trace*> traces;
};
#endif // MIXEDMODECONVERSION_H

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MixedModeConversion</class>
<widget class="QDialog" name="MixedModeConversion">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>861</width>
<height>360</height>
</rect>
</property>
<property name="windowTitle">
<string>Single-ended to Mixed-mode S-parameter conversion setup</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Single-ended source traces</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="TraceSetSelector" name="selector" native="true"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Mixed-mode destination traces</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Prefix:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="prefix"/>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="list"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>TraceSetSelector</class>
<extends>QWidget</extends>
<header>CustomWidgets/tracesetselector.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -9,18 +9,13 @@
TraceTouchstoneExport::TraceTouchstoneExport(TraceModel &model, QWidget *parent) :
QDialog(parent),
ui(new Ui::TraceTouchstoneExport),
model(model),
ports(0),
points(0),
lowerFreq(0),
upperFreq(0),
referenceImpedance(50.0),
freqsSet(false)
ui(new Ui::TraceTouchstoneExport)
{
ui->setupUi(this);
ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(false);
ui->gbTraces->setLayout(new QGridLayout);
ui->selector->setModel(&model);
ui->selector->setPartialSelectionAllowed(true);
connect(ui->selector, qOverload<>(&TraceSetSelector::selectionChanged), this, &TraceTouchstoneExport::selectionChanged);
on_sbPorts_valueChanged(ui->sbPorts->value());
}
@ -31,30 +26,7 @@ TraceTouchstoneExport::~TraceTouchstoneExport()
bool TraceTouchstoneExport::setTrace(int portFrom, int portTo, Trace *t)
{
if(t->getDataType() != Trace::DataType::Frequency) {
// can only add frequency traces
return false;
}
if(portFrom < 0 || portFrom >= ui->sbPorts->value() || portTo < 0 || portTo >= ui->sbPorts->value()) {
// invalid port selection
return false;
}
auto c = cTraces[portTo][portFrom];
if(t) {
for(int i=1;i<c->count();i++) {
if(t == qvariant_cast<Trace*>(c->itemData(i))) {
// select this trace
c->setCurrentIndex(i);
return true;
}
}
// requested trace is not an option
return false;
} else {
// select 'none' option
c->setCurrentIndex(0);
return true;
}
return ui->selector->setTrace(portTo, portFrom, t);
}
bool TraceTouchstoneExport::setPortNum(int ports)
@ -63,6 +35,7 @@ bool TraceTouchstoneExport::setPortNum(int ports)
return false;
}
ui->sbPorts->setValue(ports);
ui->selector->setPorts(ports);
return true;
}
@ -72,17 +45,17 @@ void TraceTouchstoneExport::on_buttonBox_accepted()
if(filename.length() > 0) {
auto ports = ui->sbPorts->value();
auto t = Touchstone(ports);
t.setReferenceImpedance(referenceImpedance);
t.setReferenceImpedance(ui->selector->getReferenceImpedance());
// add trace points to touchstone
for(unsigned int s=0;s<points;s++) {
for(unsigned int s=0;s<ui->selector->getPoints();s++) {
Touchstone::Datapoint tData;
for(int i=0;i<ports;i++) {
for(int j=0;j<ports;j++) {
if(cTraces[i][j]->currentIndex() == 0) {
for(int i=1;i<=ports;i++) {
for(int j=1;j<=ports;j++) {
auto t = ui->selector->getTrace(i, j);
if(!t) {
// missing trace, set to 0
tData.S.push_back(0.0);
} else {
Trace *t = qvariant_cast<Trace*>(cTraces[i][j]->itemData(cTraces[i][j]->currentIndex()));
// extract frequency (will overwrite for each trace but all traces have the same frequency points anyway)
tData.frequency = t->sample(s).x;
// add S parameter from trace to touchstone
@ -113,103 +86,22 @@ void TraceTouchstoneExport::on_buttonBox_accepted()
void TraceTouchstoneExport::on_sbPorts_valueChanged(int ports)
{
QGridLayout *layout = static_cast<QGridLayout*>(ui->gbTraces->layout());
if((unsigned) ports != this->ports) {
this->ports = ports;
// remove the previous widgets
QLayoutItem *child;
while ((child = layout->takeAt(0)) != 0) {
delete child->widget();
delete child;
}
cTraces.clear();
for(int i=0;i<ports;i++) {
cTraces.push_back(std::vector<QComboBox*>());
for(int j=0;j<ports;j++) {
auto l = new QLabel("S"+QString::number(i+1)+QString::number(j+1)+":");
auto c = new QComboBox();
cTraces[i].push_back(c);
connect(c, qOverload<int>(&QComboBox::currentIndexChanged), [=](int) {
selectionChanged(c);
});
layout->addWidget(l, i, j*2);
layout->addWidget(c, i, j*2 + 1);
}
}
}
auto availableTraces = model.getTraces();
for(int i=0;i<ports;i++) {
for(int j=0;j<ports;j++) {
auto c = cTraces[i][j];
c->blockSignals(true);
c->clear();
// create possible trace selections
c->addItem("None");
for(auto t : availableTraces) {
if(t->getDataType() != Trace::DataType::Frequency) {
// can only add frequency traces
continue;
}
if(i == j && !t->isReflection()) {
// can not add through measurement at reflection port
continue;
} else if(i != j && t->isReflection()) {
// can not add reflection measurement at through port
continue;
}
c->addItem(t->name(), QVariant::fromValue<Trace*>(t));
}
c->blockSignals(false);
}
}
ui->selector->setPorts(ports);
}
void TraceTouchstoneExport::selectionChanged(QComboBox *w)
void TraceTouchstoneExport::selectionChanged()
{
if(w->currentIndex() != 0 && !freqsSet) {
// the first trace has been selected, extract frequency info
Trace *t = qvariant_cast<Trace*>(w->itemData(w->currentIndex()));
points = t->size();
referenceImpedance = t->getReferenceImpedance();
ui->points->setText(QString::number(points));
if(points > 0) {
lowerFreq = t->minX();
upperFreq = t->maxX();
ui->lowerFreq->setText(QString::number(lowerFreq));
ui->upperFreq->setText(QString::number(upperFreq));
auto valid = ui->selector->selectionValid();
ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(valid);
if(valid) {
ui->points->setText(QString::number(ui->selector->getPoints()));
if(ui->selector->getPoints() > 0) {
ui->lowerFreq->setText(QString::number(ui->selector->getLowerFreq()));
ui->upperFreq->setText(QString::number(ui->selector->getUpperFreq()));
}
freqsSet = true;
ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(true);
// remove all trace options with incompatible frequencies
for(auto v1 : cTraces) {
for(auto c : v1) {
for(int i=1;i<c->count();i++) {
Trace *t = qvariant_cast<Trace*>(c->itemData(i));
if(t->getReferenceImpedance() != referenceImpedance || t->size() != points || (points > 0 && (t->minX() != lowerFreq || t->maxX() != upperFreq))) {
// this trace is not available anymore
c->removeItem(i);
// decrement to check the next index in the next loop iteration
i--;
}
}
}
}
} else if(w->currentIndex() == 0 && freqsSet) {
// Check if all trace selections are set for none
for(auto v1 : cTraces) {
for(auto c : v1) {
if(c->currentIndex() != 0) {
// some trace is still selected, abort
return;
}
}
}
// all traces set for none
freqsSet = false;
} else {
ui->points->clear();
ui->lowerFreq->clear();
ui->upperFreq->clear();
ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(false);
on_sbPorts_valueChanged(ui->sbPorts->value());
}
}

View File

@ -24,18 +24,10 @@ public:
private slots:
void on_buttonBox_accepted();
void on_sbPorts_valueChanged(int ports);
void selectionChanged(QComboBox *w);
void selectionChanged();
private:
Ui::TraceTouchstoneExport *ui;
TraceModel &model;
std::vector<std::vector<QComboBox*>> cTraces;
unsigned int ports;
unsigned int points;
double lowerFreq, upperFreq;
double referenceImpedance;
bool freqsSet;
};
#endif // TRACEEXPORTDIALOG_H

View File

@ -68,6 +68,11 @@
<property name="title">
<string>Traces</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="TraceSetSelector" name="selector" native="true"/>
</item>
</layout>
</widget>
</item>
<item>
@ -221,6 +226,14 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>TraceSetSelector</class>
<extends>QWidget</extends>
<header>CustomWidgets/tracesetselector.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>

View File

@ -34,7 +34,7 @@ TraceWidgetVNA::TraceWidgetVNA(TraceModel &model, Calibration &cal, Deembedding
if(i >= traces.size()) {
break;
}
e->setTrace(i%2, i/2, traces[i]);
e->setTrace(i%2+1, i/2+1, traces[i]);
}
if(AppWindow::showGUI()) {
e->show();

View File

@ -12,6 +12,7 @@
#include "CustomWidgets/siunitedit.h"
#include "Traces/Marker/markerwidget.h"
#include "Tools/impedancematchdialog.h"
#include "Tools/mixedmodeconversion.h"
#include "ui_main.h"
#include "Device/firmwareupdatedialog.h"
#include "preferences.h"
@ -188,6 +189,8 @@ VNA::VNA(AppWindow *window, QString name)
actions.insert(toolsMenu->menuAction());
auto impedanceMatching = toolsMenu->addAction("Impedance Matching");
connect(impedanceMatching, &QAction::triggered, this, &VNA::StartImpedanceMatching);
auto mixedMode = toolsMenu->addAction("Mixed Mode Conversion");
connect(mixedMode, &QAction::triggered, this, &VNA::StartMixedModeConversion);
defaultCalMenu = new QMenu("Default Calibration", window);
assignDefaultCal = defaultCalMenu->addAction("Assign...");
@ -913,6 +916,20 @@ void VNA::StartImpedanceMatching()
}
}
void VNA::StartMixedModeConversion()
{
auto dialog = new MixedModeConversion(traceModel);
connect(dialog, &MixedModeConversion::tracesCreated, [=](std::vector<Trace*> traces) {
auto d = new TraceImportDialog(traceModel, traces);
if(AppWindow::showGUI()) {
d->show();
}
});
if(AppWindow::showGUI()) {
dialog->show();
}
}
void VNA::SetSweepType(SweepType sw)
{
if(settings.sweepType != sw) {

View File

@ -81,6 +81,7 @@ public slots:
private slots:
void NewDatapoint(VirtualDevice::VNAMeasurement m);
void StartImpedanceMatching();
void StartMixedModeConversion();
// Sweep control
void SetSweepType(SweepType sw);
void SetStartFreq(double freq);

File diff suppressed because one or more lines are too long

View File

@ -1,82 +0,0 @@
{
"calkit": {
"Description": "TRL test calibration kit",
"Manufacturer": "Hugen",
"Serialnumber": "-",
"standards": [
{
"params": {
"id": 5166523964218309461,
"isShort": true,
"name": "TRL"
},
"type": "Reflect"
},
{
"params": {
"Z0": 50.0,
"delay": 0.0,
"id": 4725361202400330854,
"loss": 0.0,
"name": "TRL"
},
"type": "Through"
},
{
"params": {
"delay": 1e-09,
"id": 10060287735088848795,
"name": "TRL"
},
"type": "Line"
}
],
"version": "1.4.0-b20e5598b"
},
"device": "205835943750",
"measurements": [
{
"data": {
"points": null,
"port": 1,
"standard": 5166523964218309461,
"timestamp": -3600
},
"type": "Reflect"
},
{
"data": {
"points": null,
"port": 1,
"standard": 5166523964218309461,
"timestamp": -3600
},
"type": "Reflect"
},
{
"data": {
"points": null,
"port1": 1,
"port2": 2,
"reverseStandard": false,
"standard": 4725361202400330854,
"timestamp": -3600
},
"type": "Through"
},
{
"data": {
"points": null,
"port1": 1,
"port2": 2,
"reverseStandard": false,
"standard": 10060287735088848795,
"timestamp": -3600
},
"type": "Line"
}
],
"ports": null,
"type": "None",
"version": "1.4.0-b20e5598b"
}

View File

@ -1,34 +0,0 @@
{
"Description": "TRL test calibration kit",
"Manufacturer": "Hugen",
"Serialnumber": "-",
"standards": [
{
"params": {
"id": 5166523964218309461,
"isShort": true,
"name": "TRL"
},
"type": "Reflect"
},
{
"params": {
"Z0": 50.0,
"delay": 0.0,
"id": 4725361202400330854,
"loss": 0.0,
"name": "TRL"
},
"type": "Through"
},
{
"params": {
"delay": 1e-09,
"id": 10060287735088848795,
"name": "TRL"
},
"type": "Line"
}
],
"version": "1.4.0-b20e5598b"
}

View File

@ -28,6 +28,7 @@ SOURCES += \
../LibreVNA-GUI/CustomWidgets/tilewidget.cpp \
../LibreVNA-GUI/CustomWidgets/toggleswitch.cpp \
../LibreVNA-GUI/CustomWidgets/touchstoneimport.cpp \
../LibreVNA-GUI/CustomWidgets/tracesetselector.cpp \
../LibreVNA-GUI/Device/compounddevice.cpp \
../LibreVNA-GUI/Device/compounddeviceeditdialog.cpp \
../LibreVNA-GUI/Device/device.cpp \
@ -43,6 +44,7 @@ SOURCES += \
../LibreVNA-GUI/SpectrumAnalyzer/tracewidgetsa.cpp \
../LibreVNA-GUI/Tools/eseries.cpp \
../LibreVNA-GUI/Tools/impedancematchdialog.cpp \
../LibreVNA-GUI/Tools/mixedmodeconversion.cpp \
../LibreVNA-GUI/Tools/parameters.cpp \
../LibreVNA-GUI/Traces/Marker/marker.cpp \
../LibreVNA-GUI/Traces/Marker/markergroup.cpp \
@ -193,6 +195,7 @@ HEADERS += \
../LibreVNA-GUI/CustomWidgets/tilewidget.h \
../LibreVNA-GUI/CustomWidgets/toggleswitch.h \
../LibreVNA-GUI/CustomWidgets/touchstoneimport.h \
../LibreVNA-GUI/CustomWidgets/tracesetselector.h \
../LibreVNA-GUI/Device/compounddevice.h \
../LibreVNA-GUI/Device/compounddeviceeditdialog.h \
../LibreVNA-GUI/Device/device.h \
@ -208,6 +211,7 @@ HEADERS += \
../LibreVNA-GUI/SpectrumAnalyzer/tracewidgetsa.h \
../LibreVNA-GUI/Tools/eseries.h \
../LibreVNA-GUI/Tools/impedancematchdialog.h \
../LibreVNA-GUI/Tools/mixedmodeconversion.h \
../LibreVNA-GUI/Tools/parameters.h \
../LibreVNA-GUI/Traces/Marker/marker.h \
../LibreVNA-GUI/Traces/Marker/markergroup.h \
@ -348,6 +352,7 @@ FORMS += \
../LibreVNA-GUI/Device/manualcontroldialog.ui \
../LibreVNA-GUI/Generator/signalgenwidget.ui \
../LibreVNA-GUI/Tools/impedancematchdialog.ui \
../LibreVNA-GUI/Tools/mixedmodeconversion.ui \
../LibreVNA-GUI/Traces/Marker/markerwidget.ui \
../LibreVNA-GUI/Traces/Math/dftdialog.ui \
../LibreVNA-GUI/Traces/Math/dftexplanationwidget.ui \