Merge branch 'master' into compoundDevice

This commit is contained in:
Jan Käberich 2022-09-04 19:15:53 +02:00
commit 00ef868671
15 changed files with 579 additions and 633 deletions

View File

@ -684,6 +684,9 @@ void Marker::traceDataChanged()
void Marker::updateSymbol() void Marker::updateSymbol()
{ {
if(isDisplayedMarker()) { if(isDisplayedMarker()) {
auto style = Preferences::getInstance().Marker.symbolStyle;
switch(style) {
case MarkerSymbolStyle::FilledNumberInside: {
constexpr int width = 15, height = 15; constexpr int width = 15, height = 15;
symbol = QPixmap(width, height); symbol = QPixmap(width, height);
symbol.fill(Qt::transparent); symbol.fill(Qt::transparent);
@ -695,7 +698,37 @@ void Marker::updateSymbol()
p.setBrush(traceColor); p.setBrush(traceColor);
p.drawConvexPolygon(points, 3); p.drawConvexPolygon(points, 3);
p.setPen(Util::getFontColorFromBackground(traceColor)); p.setPen(Util::getFontColorFromBackground(traceColor));
p.drawText(QRectF(0,0,width, height*2.0/3.0), Qt::AlignCenter, QString::number(number) + suffix); p.drawText(QRectF(0,0,width, height * 2.0 / 3.0), Qt::AlignCenter, QString::number(number) + suffix);
}
break;
case MarkerSymbolStyle::FilledNumberAbove: {
constexpr int width = 15, height = 30;
symbol = QPixmap(width, height);
symbol.fill(Qt::transparent);
QPainter p(&symbol);
p.setRenderHint(QPainter::Antialiasing);
QPointF points[] = {QPointF(0,height/2),QPointF(width,height/2),QPointF(width/2,height)};
auto traceColor = parentTrace->color();
p.setPen(traceColor);
p.setBrush(traceColor);
p.drawConvexPolygon(points, 3);
p.drawText(QRectF(0,0,width, height * 0.45), Qt::AlignCenter, QString::number(number) + suffix);
}
break;
case MarkerSymbolStyle::EmptyNumberAbove: {
constexpr int width = 15, height = 30;
symbol = QPixmap(width, height);
symbol.fill(Qt::transparent);
QPainter p(&symbol);
p.setRenderHint(QPainter::Antialiasing);
QPointF points[] = {QPointF(0,height/2),QPointF(width,height/2),QPointF(width/2,height)};
auto traceColor = parentTrace->color();
p.setPen(traceColor);
p.drawConvexPolygon(points, 3);
p.drawText(QRectF(0,0,width, height * 0.45), Qt::AlignCenter, QString::number(number) + suffix);
}
break;
}
} else { } else {
symbol = QPixmap(1,1); symbol = QPixmap(1,1);
} }

View File

@ -17,8 +17,34 @@ ImpedanceRenormalization::ImpedanceRenormalization()
void ImpedanceRenormalization::transformDatapoint(VirtualDevice::VNAMeasurement &p) void ImpedanceRenormalization::transformDatapoint(VirtualDevice::VNAMeasurement &p)
{ {
//p.S = Sparam(ABCDparam(p.S, p.Z0), impedance); std::map<QString, std::complex<double>> transformed;
// TODO int ports = 0;
QString name = "S11";
while(p.measurements.count(name) > 0) {
ports++;
name = "S"+QString::number(ports+1)+QString::number(ports+1);
}
for(auto i=1;i<=ports;i++) {
auto S11name = "S"+QString::number(i)+QString::number(i);
auto S11 = p.measurements[S11name];
transformed[S11name] = Sparam(ABCDparam(Sparam(S11, 0.0, 0.0, 1.0), p.Z0), impedance).m11;
for(auto j=i+1;j<=ports;j++) {
auto S12name = "S"+QString::number(i)+QString::number(j);
auto S21name = "S"+QString::number(j)+QString::number(i);
auto S22name = "S"+QString::number(j)+QString::number(j);
if(!p.measurements.count(S12name) || !p.measurements.count(S21name) || !p.measurements.count(S22name)) {
// not all measurements available, skip this
continue;
}
auto S12 = p.measurements[S12name];
auto S21 = p.measurements[S21name];
auto S22 = p.measurements[S22name];
auto S_t = Sparam(ABCDparam(Sparam(S11, S12, S21, S22), p.Z0), impedance);
transformed[S12name] = S_t.m12;
transformed[S21name] = S_t.m21;
}
}
p.measurements = transformed;
p.Z0 = impedance; p.Z0 = impedance;
} }

View File

@ -24,6 +24,7 @@ MatchingNetwork::MatchingNetwork()
dragComponent = nullptr; dragComponent = nullptr;
dropComponent = nullptr; dropComponent = nullptr;
addNetwork = true; addNetwork = true;
port = 1;
} }
void MatchingNetwork::transformDatapoint(VirtualDevice::VNAMeasurement &p) void MatchingNetwork::transformDatapoint(VirtualDevice::VNAMeasurement &p)
@ -34,26 +35,40 @@ void MatchingNetwork::transformDatapoint(VirtualDevice::VNAMeasurement &p)
// this point is not calculated yet // this point is not calculated yet
MatchingPoint m; MatchingPoint m;
// start with identiy matrix // start with identiy matrix
m.p1 = ABCDparam(1.0,0.0,0.0,1.0); m.p = ABCDparam(1.0,0.0,0.0,1.0);
for(auto c : p1Network) { for(auto c : network) {
m.p1 = m.p1 * c->parameters(p.frequency); m.p = m.p * c->parameters(p.frequency);
}
// same for network at port 2
m.p2 = ABCDparam(1.0,0.0,0.0,1.0);
for(auto c : p2Network) {
m.p2 = m.p2 * c->parameters(p.frequency);
} }
if(!addNetwork) { if(!addNetwork) {
// need to remove the effect of the networks, invert matrices // need to remove the effect of the network, invert matrix
m.p1 = m.p1.inverse(); m.p = m.p.inverse();
m.p2 = m.p2.inverse();
} }
matching[p.frequency] = m; matching[p.frequency] = m;
} }
// at this point the map contains the matching network effect // at this point the map contains the matching network effect
auto m = matching[p.frequency]; auto m = matching[p.frequency];
auto corrected = m.p1 * measurement * m.p2; VirtualDevice::VNAMeasurement uncorrected = p;
p.fromSparam(Sparam(corrected, p.Z0), 1, 2); // correct reflection measurement (in case no two-port measurement is complete
QString name = "S"+QString::number(port)+QString::number(port);
if(uncorrected.measurements.count(name) > 0) {
auto S = Sparam(uncorrected.measurements[name], 0.0, 0.0, 1.0);
auto corrected = Sparam(m.p * ABCDparam(S, p.Z0), p.Z0);
p.measurements[name] = corrected.m11;
}
// handle the rest of the measurements
for(int i=0;i<VirtualDevice::getInfo(VirtualDevice::getConnected()).ports;i++) {
for(int j=i+1;j<VirtualDevice::getInfo(VirtualDevice::getConnected()).ports;j++) {
if(i == port) {
auto S = uncorrected.toSparam(i, j);
auto corrected = Sparam(m.p * ABCDparam(S, p.Z0), p.Z0);
p.fromSparam(corrected, i, j);
} else if(j == port) {
auto S = uncorrected.toSparam(i, j);
auto corrected = Sparam(ABCDparam(S, p.Z0) * m.p, p.Z0);
p.fromSparam(corrected, i, j);
}
}
}
} }
void MatchingNetwork::edit() void MatchingNetwork::edit()
@ -80,6 +95,10 @@ void MatchingNetwork::edit()
ui->lParallelL->installEventFilter(this); ui->lParallelL->installEventFilter(this);
ui->lParallelR->installEventFilter(this); ui->lParallelR->installEventFilter(this);
ui->lDefinedThrough->installEventFilter(this); ui->lDefinedThrough->installEventFilter(this);
ui->port->setValue(port);
ui->port->setMaximum(VirtualDevice::getInfo(VirtualDevice::getConnected()).ports);
layout->setContentsMargins(0,0,0,0); layout->setContentsMargins(0,0,0,0);
layout->setSpacing(0); layout->setSpacing(0);
layout->addStretch(1); layout->addStretch(1);
@ -93,26 +112,15 @@ void MatchingNetwork::edit()
DUT->setMaximumSize(DUTWidth, 151); DUT->setMaximumSize(DUTWidth, 151);
DUT->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); DUT->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
DUT->setStyleSheet("image: url(:/icons/DUT.png);"); DUT->setStyleSheet("image: url(:/icons/DUT.png);");
auto p2 = new QWidget();
p2->setMinimumSize(portWidth, 151);
p2->setMaximumSize(portWidth, 151);
p2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
p2->setStyleSheet("image: url(:/icons/port2.png);");
layout->addWidget(p1); layout->addWidget(p1);
for(auto w : p1Network) { for(auto w : network) {
layout->addWidget(w); layout->addWidget(w);
connect(w, &MatchingComponent::MatchingComponent::valueChanged, [=](){ connect(w, &MatchingComponent::MatchingComponent::valueChanged, [=](){
matching.clear(); matching.clear();
}); });
} }
layout->addWidget(DUT); layout->addWidget(DUT);
for(auto w : p2Network) {
layout->addWidget(w);
connect(w, &MatchingComponent::MatchingComponent::valueChanged, [=](){
matching.clear();
});
}
layout->addWidget(p2);
layout->addStretch(1); layout->addStretch(1);
@ -129,37 +137,34 @@ void MatchingNetwork::edit()
// network changed, need to recalculate matching // network changed, need to recalculate matching
matching.clear(); matching.clear();
}); });
connect(ui->port, qOverload<int>(&QSpinBox::valueChanged), [=](){
port = ui->port->value();
});
connect(ui->buttonBox, &QDialogButtonBox::accepted, dialog, &QDialog::accept); connect(ui->buttonBox, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
} }
nlohmann::json MatchingNetwork::toJSON() nlohmann::json MatchingNetwork::toJSON()
{ {
nlohmann::json j; nlohmann::json j;
nlohmann::json jn1, jn2; nlohmann::json jn;
for(auto c : p1Network) { for(auto c : network) {
nlohmann::json jc; nlohmann::json jc;
jc["component"] = c->getName().toStdString(); jc["component"] = c->getName().toStdString();
jc["params"] = c->toJSON(); jc["params"] = c->toJSON();
jn1.push_back(jc); jn.push_back(jc);
} }
for(auto c : p2Network) { j["port"] = port;
nlohmann::json jc; j["network"] = jn;
jc["component"] = c->getName().toStdString();
jc["params"] = c->toJSON();
jn2.push_back(jc);
}
j["port1"] = jn1;
j["port2"] = jn2;
j["addNetwork"] = addNetwork; j["addNetwork"] = addNetwork;
return j; return j;
} }
void MatchingNetwork::fromJSON(nlohmann::json j) void MatchingNetwork::fromJSON(nlohmann::json j)
{ {
p1Network.clear(); network.clear();
p2Network.clear(); port = j.value("port", 1);
if(j.contains("port1")) { if(j.contains("network")) {
for(auto jc : j["port1"]) { for(auto jc : j["network"]) {
if(!jc.contains("component")) { if(!jc.contains("component")) {
continue; continue;
} }
@ -168,20 +173,7 @@ void MatchingNetwork::fromJSON(nlohmann::json j)
continue; continue;
} }
c->fromJSON(jc["params"]); c->fromJSON(jc["params"]);
p1Network.push_back(c); network.push_back(c);
}
}
if(j.contains("port2")) {
for(auto jc : j["port2"]) {
if(!jc.contains("component")) {
continue;
}
auto c = MatchingComponent::createFromName(QString::fromStdString(jc["component"]));
if(!c) {
continue;
}
c->fromJSON(jc["params"]);
p2Network.push_back(c);
} }
} }
addNetwork = j.value("addNetwork", true); addNetwork = j.value("addNetwork", true);
@ -192,15 +184,9 @@ MatchingComponent *MatchingNetwork::componentAtPosition(int pos)
{ {
pos -= graph->layout()->itemAt(0)->geometry().width(); pos -= graph->layout()->itemAt(0)->geometry().width();
pos -= portWidth; pos -= portWidth;
if(pos > 0 && pos <= (int) p1Network.size() * componentWidth) { if(pos > 0 && pos <= (int) network.size() * componentWidth) {
// position is in port 1 network // position is in port 1 network
return p1Network[pos / componentWidth]; return network[pos / componentWidth];
} else if(pos > (int) p1Network.size() * componentWidth + DUTWidth) {
pos -= (int) p1Network.size() * componentWidth + DUTWidth;
if(pos <= (int) p2Network.size() * componentWidth) {
// position is in port 2 network
return p2Network[pos / componentWidth];
}
} }
return nullptr; return nullptr;
} }
@ -209,28 +195,15 @@ unsigned int MatchingNetwork::findInsertPosition(int xcoord)
{ {
xcoord -= graph->layout()->itemAt(0)->geometry().width(); xcoord -= graph->layout()->itemAt(0)->geometry().width();
xcoord -= portWidth; xcoord -= portWidth;
if(xcoord <= (int) p1Network.size() * componentWidth + DUTWidth/2) {
// added in port 1 network // added in port 1 network
int index = (xcoord + componentWidth / 2) / componentWidth; int index = (xcoord + componentWidth / 2) / componentWidth;
if(index < 0) { if(index < 0) {
index = 0; index = 0;
} else if(index > (int) p1Network.size()) { } else if(index > (int) network.size()) {
index = p1Network.size(); index = network.size();
} }
// add 2 (first two widgets are always the stretch and port 1 widget) // add 2 (first two widgets are always the stretch and port 1 widget)
return index + 2; return index + 2;
} else {
// added in port 2 network
xcoord -= (int) p1Network.size() * componentWidth + DUTWidth;
int index = (xcoord + componentWidth / 2) / componentWidth;
if(index < 0) {
index = 0;
} else if(index > (int) p2Network.size()) {
index = p2Network.size();
}
// add 3 (same two widgets as in port 1 + DUT) and the size of the port 1 network
return index + 3 + p1Network.size();
}
} }
void MatchingNetwork::addComponentAtPosition(int pos, MatchingComponent *c) void MatchingNetwork::addComponentAtPosition(int pos, MatchingComponent *c)
@ -242,12 +215,7 @@ void MatchingNetwork::addComponentAtPosition(int pos, MatchingComponent *c)
// add component to correct matching network // add component to correct matching network
index -= 2; // first two widgets are fixed index -= 2; // first two widgets are fixed
if(index <= p1Network.size()) { addComponent(index, c);
addComponent(true, index, c);
} else {
index -= 1 + p1Network.size();
addComponent(false, index, c);
}
// network changed, need to recalculate matching // network changed, need to recalculate matching
matching.clear(); matching.clear();
@ -256,22 +224,13 @@ void MatchingNetwork::addComponentAtPosition(int pos, MatchingComponent *c)
}); });
} }
void MatchingNetwork::addComponent(bool port1, int index, MatchingComponent *c) void MatchingNetwork::addComponent(int index, MatchingComponent *c)
{ {
if(port1) { network.insert(network.begin() + index, c);
p1Network.insert(p1Network.begin() + index, c);
// remove from list when the component deletes itself // remove from list when the component deletes itself
connect(c, &MatchingComponent::deleted, [=](){ connect(c, &MatchingComponent::deleted, [=](){
p1Network.erase(remove(p1Network.begin(), p1Network.end(), c), p1Network.end()); network.erase(remove(network.begin(), network.end(), c), network.end());
}); });
} else {
// same procedure for port 2 network
p2Network.insert(p2Network.begin() + index, c);
// remove from list when the component deletes itself
connect(c, &MatchingComponent::deleted, [=](){
p2Network.erase(remove(p2Network.begin(), p2Network.end(), c), p2Network.end());
});
}
} }
void MatchingNetwork::createDragComponent(MatchingComponent *c) void MatchingNetwork::createDragComponent(MatchingComponent *c)
@ -326,8 +285,7 @@ bool MatchingNetwork::eventFilter(QObject *object, QEvent *event)
// remove and hide component while it is being dragged // remove and hide component while it is being dragged
graph->layout()->removeWidget(dragComponent); graph->layout()->removeWidget(dragComponent);
dragComponent->hide(); dragComponent->hide();
p1Network.erase(remove(p1Network.begin(), p1Network.end(), dragComponent), p1Network.end()); network.erase(remove(network.begin(), network.end(), dragComponent), network.end());
p2Network.erase(remove(p2Network.begin(), p2Network.end(), dragComponent), p2Network.end());
graph->update(); graph->update();
// network changed, need to recalculate matching // network changed, need to recalculate matching

View File

@ -77,11 +77,13 @@ private:
MatchingComponent *componentAtPosition(int pos); MatchingComponent *componentAtPosition(int pos);
unsigned int findInsertPosition(int xcoord); unsigned int findInsertPosition(int xcoord);
void addComponentAtPosition(int pos, MatchingComponent *c); void addComponentAtPosition(int pos, MatchingComponent *c);
void addComponent(bool port1, int index, MatchingComponent *c); void addComponent(int index, MatchingComponent *c);
void createDragComponent(MatchingComponent *c); void createDragComponent(MatchingComponent *c);
void updateInsertIndicator(int xcoord); void updateInsertIndicator(int xcoord);
bool eventFilter(QObject *object, QEvent *event) override; bool eventFilter(QObject *object, QEvent *event) override;
std::vector<MatchingComponent*> p1Network, p2Network;
std::vector<MatchingComponent*> network;
int port;
QWidget *graph, *insertIndicator; QWidget *graph, *insertIndicator;
QPoint dragStartPosition; QPoint dragStartPosition;
@ -91,7 +93,7 @@ private:
class MatchingPoint { class MatchingPoint {
public: public:
ABCDparam p1, p2; ABCDparam p;
}; };
std::map<double, MatchingPoint> matching; std::map<double, MatchingPoint> matching;

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>772</width> <width>913</width>
<height>443</height> <height>633</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -21,6 +21,37 @@
</string> </string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_9"> <layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Port:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="port">
<property name="minimum">
<number>1</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_8"> <layout class="QVBoxLayout" name="verticalLayout_8">
<item> <item>
@ -48,7 +79,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>750</width> <width>891</width>
<height>168</height> <height>168</height>
</rect> </rect>
</property> </property>

View File

@ -13,50 +13,35 @@ using namespace std;
PortExtension::PortExtension() PortExtension::PortExtension()
: DeembeddingOption() : DeembeddingOption()
{ {
port1.enabled = false; ext.frequency = 0;
port1.frequency = 0; ext.loss = 0;
port1.loss = 0; ext.DCloss = 0;
port1.DCloss = 0; ext.delay = 0;
port1.delay = 0; ext.velocityFactor = 0.66;
port1.velocityFactor = 0.66;
port2.enabled = false; port = 1;
port2.frequency = 0;
port2.loss = 0;
port2.DCloss = 0;
port2.delay = 0;
port2.velocityFactor = 0.66;
kit = nullptr; kit = nullptr;
} }
void PortExtension::transformDatapoint(VirtualDevice::VNAMeasurement &d) void PortExtension::transformDatapoint(VirtualDevice::VNAMeasurement &d)
{ {
if(port1.enabled || port2.enabled) { auto phase = -2 * M_PI * ext.delay * d.frequency;
if(port1.enabled) { auto db_attennuation = ext.DCloss;
auto phase = -2 * M_PI * port1.delay * d.frequency; if(ext.frequency != 0) {
auto db_attennuation = port1.DCloss; db_attennuation += ext.loss * sqrt(d.frequency / ext.frequency);
if(port1.frequency != 0) {
db_attennuation += port1.loss * sqrt(d.frequency / port1.frequency);
} }
// convert from db to factor // convert from db to factor
auto att = pow(10.0, -db_attennuation / 20.0); auto att = pow(10.0, -db_attennuation / 20.0);
auto correction = polar<double>(att, phase); auto correction = polar<double>(att, phase);
d.measurements["S11"] /= correction * correction; for(auto &m : d.measurements) {
d.measurements["S21"] /= correction; if(m.first.mid(1, 1).toInt() == port) {
d.measurements["S12"] /= correction; // selected port is the destination of this S parameter
m.second /= correction;
} }
if(port2.enabled) { if(m.first.mid(2, 1).toInt() == port) {
auto phase = -2 * M_PI * port2.delay * d.frequency; // selected port is the source of this S parameter
auto db_attennuation = port2.DCloss; m.second /= correction;
if(port2.frequency != 0) {
db_attennuation += port2.loss * sqrt(d.frequency / port2.frequency);
}
// convert from db to factor
auto att = pow(10.0, -db_attennuation / 20.0);
auto correction = polar<double>(att, phase);
d.measurements["S22"] /= correction * correction;
d.measurements["S21"] /= correction;
d.measurements["S12"] /= correction;
} }
} }
} }
@ -73,117 +58,56 @@ void PortExtension::edit()
}); });
// set initial values // set initial values
ui->P1Enabled->setChecked(port1.enabled); ui->Time->setUnit("s");
ui->P1Time->setUnit("s"); ui->Time->setPrefixes("pnum ");
ui->P1Time->setPrefixes("pnum "); ui->Distance->setUnit("m");
ui->P1Distance->setUnit("m"); ui->Distance->setPrefixes("m ");
ui->P1Distance->setPrefixes("m "); ui->DCloss->setUnit("db");
ui->P1DCloss->setUnit("db"); ui->Loss->setUnit("db");
ui->P1Loss->setUnit("db"); ui->Frequency->setUnit("Hz");
ui->P1Frequency->setUnit("Hz"); ui->Frequency->setPrefixes(" kMG");
ui->P1Frequency->setPrefixes(" kMG"); ui->Time->setValue(ext.delay);
ui->P1Time->setValue(port1.delay); ui->Velocity->setValue(ext.velocityFactor);
ui->P1Velocity->setValue(port1.velocityFactor); ui->Distance->setValue(ext.delay * ext.velocityFactor * c);
ui->P1Distance->setValue(port1.delay * port1.velocityFactor * c); ui->DCloss->setValue(ext.DCloss);
ui->P1DCloss->setValue(port1.DCloss); ui->Loss->setValue(ext.loss);
ui->P1Loss->setValue(port1.loss); ui->Frequency->setValue(ext.frequency);
ui->P1Frequency->setValue(port1.frequency);
if(!kit) { if(!kit) {
ui->P1calkit->setEnabled(false); ui->calkit->setEnabled(false);
}
ui->P2Enabled->setChecked(port2.enabled);
ui->P2Time->setUnit("s");
ui->P2Time->setPrefixes("pnum ");
ui->P2Distance->setUnit("m");
ui->P2Distance->setPrefixes("m ");
ui->P2DCloss->setUnit("db");
ui->P2Loss->setUnit("db");
ui->P2Frequency->setUnit("Hz");
ui->P2Frequency->setPrefixes(" kMG");
ui->P2Time->setValue(port2.delay);
ui->P2Velocity->setValue(port2.velocityFactor);
ui->P2Distance->setValue(port2.delay * port2.velocityFactor * c);
ui->P2DCloss->setValue(port2.DCloss);
ui->P2Loss->setValue(port2.loss);
ui->P2Frequency->setValue(port2.frequency);
if(!kit) {
ui->P2calkit->setEnabled(false);
} }
auto updateValuesFromUI = [=](){ auto updateValuesFromUI = [=](){
port1.delay = ui->P1Time->value(); ext.delay = ui->Time->value();
port1.velocityFactor = ui->P1Velocity->value(); ext.velocityFactor = ui->Velocity->value();
port1.DCloss = ui->P1DCloss->value(); ext.DCloss = ui->DCloss->value();
port1.loss = ui->P1Loss->value(); ext.loss = ui->Loss->value();
port1.frequency = ui->P1Frequency->value(); ext.frequency = ui->Frequency->value();
port2.delay = ui->P2Time->value();
port2.velocityFactor = ui->P2Velocity->value();
port2.DCloss = ui->P2DCloss->value();
port2.loss = ui->P2Loss->value();
port2.frequency = ui->P2Frequency->value();
}; };
connect(ui->P1Enabled, &QCheckBox::toggled, [=](bool enabled) {
port1.enabled = enabled;
});
// connections to link delay and distance // connections to link delay and distance
connect(ui->P1Time, &SIUnitEdit::valueChanged, [=](double newval) { connect(ui->Time, &SIUnitEdit::valueChanged, [=](double newval) {
ui->P1Distance->setValueQuiet(newval * ui->P1Velocity->value() * c); ui->Distance->setValueQuiet(newval * ui->Velocity->value() * c);
updateValuesFromUI(); updateValuesFromUI();
}); });
connect(ui->P1Distance, &SIUnitEdit::valueChanged, [=](double newval) { connect(ui->Distance, &SIUnitEdit::valueChanged, [=](double newval) {
ui->P1Time->setValueQuiet(newval / (ui->P1Velocity->value() * c)); ui->Time->setValueQuiet(newval / (ui->Velocity->value() * c));
updateValuesFromUI(); updateValuesFromUI();
}); });
connect(ui->P1Velocity, &SIUnitEdit::valueChanged, [=](double newval) { connect(ui->Velocity, &SIUnitEdit::valueChanged, [=](double newval) {
ui->P1Time->setValueQuiet(ui->P1Distance->value() / (newval * c)); ui->Time->setValueQuiet(ui->Distance->value() / (newval * c));
updateValuesFromUI(); updateValuesFromUI();
}); });
connect(ui->P1DCloss, &SIUnitEdit::valueChanged, updateValuesFromUI); connect(ui->DCloss, &SIUnitEdit::valueChanged, updateValuesFromUI);
connect(ui->P1Loss, &SIUnitEdit::valueChanged, updateValuesFromUI); connect(ui->Loss, &SIUnitEdit::valueChanged, updateValuesFromUI);
connect(ui->P1Frequency, &SIUnitEdit::valueChanged, updateValuesFromUI); connect(ui->Frequency, &SIUnitEdit::valueChanged, updateValuesFromUI);
connect(ui->P1short, &QPushButton::pressed, [=](){ connect(ui->_short, &QPushButton::pressed, [=](){
isOpen = false; isOpen = false;
isPort1 = true; isIdeal = ui->ideal->isChecked();
isIdeal = ui->P1ideal->isChecked();
startMeasurement(); startMeasurement();
}); });
connect(ui->P1open, &QPushButton::pressed, [=](){ connect(ui->open, &QPushButton::pressed, [=](){
isOpen = true; isOpen = true;
isPort1 = true; isIdeal = ui->ideal->isChecked();
isIdeal = ui->P1ideal->isChecked();
startMeasurement();
});
connect(ui->P2Enabled, &QCheckBox::toggled, [=](bool enabled) {
port2.enabled = enabled;
});
connect(ui->P2Time, &SIUnitEdit::valueChanged, [=](double newval) {
ui->P2Distance->setValueQuiet(newval * ui->P2Velocity->value() * c);
updateValuesFromUI();
});
connect(ui->P2Distance, &SIUnitEdit::valueChanged, [=](double newval) {
ui->P2Time->setValueQuiet(newval / (ui->P2Velocity->value() * c));
updateValuesFromUI();
});
connect(ui->P2Velocity, &SIUnitEdit::valueChanged, [=](double newval) {
ui->P2Time->setValueQuiet(ui->P2Distance->value() / (newval * c));
updateValuesFromUI();
});
connect(ui->P2DCloss, &SIUnitEdit::valueChanged, updateValuesFromUI);
connect(ui->P2Loss, &SIUnitEdit::valueChanged, updateValuesFromUI);
connect(ui->P2Frequency, &SIUnitEdit::valueChanged, updateValuesFromUI);
connect(ui->P2short, &QPushButton::pressed, [=](){
isOpen = false;
isPort1 = false;
isIdeal = ui->P2ideal->isChecked();
startMeasurement();
});
connect(ui->P2open, &QPushButton::pressed, [=](){
isOpen = true;
isPort1 = false;
isIdeal = ui->P2ideal->isChecked();
startMeasurement(); startMeasurement();
}); });
@ -203,22 +127,17 @@ void PortExtension::measurementCompleted(std::vector<VirtualDevice::VNAMeasureme
double avg_x = 0.0, avg_y = 0.0; double avg_x = 0.0, avg_y = 0.0;
for(auto p : m) { for(auto p : m) {
// grab correct measurement // grab correct measurement
complex<double> reflection; QString name = "S"+QString::number(port)+QString::number(port);
if(isPort1) { auto reflection = p.measurements[name];
reflection = p.measurements["S11"];
} else {
reflection = p.measurements["S22"];
}
// remove calkit if specified // remove calkit if specified
if(!isIdeal) { if(!isIdeal) {
complex<double> calStandard = 1.0; complex<double> calStandard = 1.0;
// TODO auto comp = isOpen ? CalStandard::Virtual::Type::Open : CalStandard::Virtual::Type::Short;
// auto standards = kit->toSOLT(p.frequency); for(auto s : kit->getStandards()) {
// if(isOpen) { if(s->getType() == comp) {
// calStandard = standards.Open; calStandard = static_cast<CalStandard::OnePort*>(s)->toS11(p.frequency);
// } else { }
// calStandard = standards.Short; }
// }
// remove effect of calibration standard // remove effect of calibration standard
reflection /= calStandard; reflection /= calStandard;
} }
@ -266,23 +185,16 @@ void PortExtension::measurementCompleted(std::vector<VirtualDevice::VNAMeasureme
double DCloss = -alpha / 2; double DCloss = -alpha / 2;
double loss = -beta / 2; double loss = -beta / 2;
double freq = m.back().frequency; double freq = m.back().frequency;
if(isPort1) { ui->Time->setValue(delay);
ui->P1Time->setValue(delay); ui->DCloss->setValue(DCloss);
ui->P1DCloss->setValue(DCloss); ui->Loss->setValue(loss);
ui->P1Loss->setValue(loss); ui->Frequency->setValue(freq);
ui->P1Frequency->setValue(freq);
} else {
ui->P2Time->setValue(delay);
ui->P2DCloss->setValue(DCloss);
ui->P2Loss->setValue(loss);
ui->P2Frequency->setValue(freq);
}
} }
} }
void PortExtension::startMeasurement() void PortExtension::startMeasurement()
{ {
emit triggerMeasurement(isPort1, false, false, !isPort1); emit triggerMeasurement();
} }
void PortExtension::setCalkit(Calkit *kit) void PortExtension::setCalkit(Calkit *kit)
@ -293,35 +205,28 @@ void PortExtension::setCalkit(Calkit *kit)
nlohmann::json PortExtension::toJSON() nlohmann::json PortExtension::toJSON()
{ {
nlohmann::json j; nlohmann::json j;
for(int i=0;i<2;i++) { j["port"] = port;
auto ext = i == 0 ? port1 : port2; j["delay"] = ext.delay;
nlohmann::json je; j["velocityFactor"] = ext.velocityFactor;
je["enabled"] = ext.enabled; j["DCloss"] = ext.DCloss;
je["delay"] = ext.delay; j["loss"] = ext.loss;
je["velocityFactor"] = ext.velocityFactor; j["frequency"] = ext.frequency;
je["DCloss"] = ext.DCloss;
je["loss"] = ext.loss;
je["frequency"] = ext.frequency;
j.push_back(je);
}
return j; return j;
} }
void PortExtension::fromJSON(nlohmann::json j) void PortExtension::fromJSON(nlohmann::json j)
{ {
for(int i=0;i<2;i++) { nlohmann::json jfrom;
Extension ext; if(j.contains("port")) {
nlohmann::json je = j[i]; // new format
ext.enabled = je.value("enabled", false); jfrom = j;
ext.delay = je.value("delay", 0.0);
ext.velocityFactor = je.value("velocityFactor", 0.66);
ext.DCloss = je.value("DCloss", 0.0);
ext.loss = je.value("loss", 0.0);
ext.frequency = je.value("frequency", 6000000000);
if(i==0) {
port1 = ext;
} else { } else {
port2 = ext; jfrom = j[0];
} port = 1;
} }
ext.delay = jfrom.value("delay", 0.0);
ext.velocityFactor = jfrom.value("velocityFactor", 0.66);
ext.DCloss = jfrom.value("DCloss", 0.0);
ext.loss = jfrom.value("loss", 0.0);
ext.frequency = jfrom.value("frequency", 6000000000);
} }

View File

@ -31,18 +31,17 @@ private:
void startMeasurement(); void startMeasurement();
class Extension { class Extension {
public: public:
bool enabled;
double delay; double delay;
double velocityFactor; double velocityFactor;
double DCloss; double DCloss;
double loss; double loss;
double frequency; double frequency;
}; };
Extension port1, port2; Extension ext;
// status variables for automatic measurements // status variables for automatic measurements
Calkit *kit; Calkit *kit;
bool isPort1; int port;
bool isOpen; bool isOpen;
bool isIdeal; bool isIdeal;

View File

@ -9,8 +9,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>318</width> <width>312</width>
<height>505</height> <height>459</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -21,22 +21,23 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item> <item>
<widget class="QTabWidget" name="tabWidget"> <layout class="QFormLayout" name="formLayout_2">
<property name="currentIndex"> <item row="0" column="0">
<number>0</number> <widget class="QLabel" name="label_11">
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Port 1</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QCheckBox" name="P1Enabled">
<property name="text"> <property name="text">
<string>Enabled</string> <string>Port:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1">
<widget class="QSpinBox" name="port">
<property name="minimum">
<number>1</number>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="title"> <property name="title">
@ -51,7 +52,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="SIUnitEdit" name="P1Distance"/> <widget class="SIUnitEdit" name="Distance"/>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
@ -61,7 +62,7 @@
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
<widget class="SIUnitEdit" name="P1Time"/> <widget class="SIUnitEdit" name="Time"/>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
@ -71,7 +72,7 @@
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="SIUnitEdit" name="P1Velocity"/> <widget class="SIUnitEdit" name="Velocity"/>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -92,7 +93,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="SIUnitEdit" name="P1DCloss"/> <widget class="SIUnitEdit" name="DCloss"/>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
@ -112,7 +113,7 @@
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="SIUnitEdit" name="P1Loss"/> <widget class="SIUnitEdit" name="Loss"/>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_5">
@ -122,7 +123,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="SIUnitEdit" name="P1Frequency"/> <widget class="SIUnitEdit" name="Frequency"/>
</item> </item>
</layout> </layout>
</item> </item>
@ -136,7 +137,7 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<widget class="QRadioButton" name="P1ideal"> <widget class="QRadioButton" name="ideal">
<property name="text"> <property name="text">
<string>Assume ideal open/short</string> <string>Assume ideal open/short</string>
</property> </property>
@ -146,7 +147,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QRadioButton" name="P1calkit"> <widget class="QRadioButton" name="calkit">
<property name="text"> <property name="text">
<string>Use definition from calibration kit</string> <string>Use definition from calibration kit</string>
</property> </property>
@ -155,14 +156,14 @@
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
<widget class="QPushButton" name="P1short"> <widget class="QPushButton" name="_short">
<property name="text"> <property name="text">
<string>Measure short</string> <string>Measure short</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="P1open"> <widget class="QPushButton" name="open">
<property name="text"> <property name="text">
<string>Measure open</string> <string>Measure open</string>
</property> </property>
@ -173,160 +174,6 @@
</layout> </layout>
</widget> </widget>
</item> </item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Port 2</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QCheckBox" name="P2Enabled">
<property name="text">
<string>Enabled</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Delay</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Distance:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="SIUnitEdit" name="P2Distance"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Time:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SIUnitEdit" name="P2Time"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Velocity Factor:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SIUnitEdit" name="P2Velocity"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Loss</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>At DC:</string>
</property>
</widget>
</item>
<item>
<widget class="SIUnitEdit" name="P2DCloss"/>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="SIUnitEdit" name="P2Loss"/>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>at</string>
</property>
</widget>
</item>
<item>
<widget class="SIUnitEdit" name="P2Frequency"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Determine automatically</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QRadioButton" name="P2ideal">
<property name="text">
<string>Assume ideal open/short</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="P2calkit">
<property name="text">
<string>Use definition from calibration kit</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QPushButton" name="P2short">
<property name="text">
<string>Measure short</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="P2open">
<property name="text">
<string>Measure open</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item> <item>
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">

View File

@ -13,13 +13,15 @@ using namespace std;
TwoThru::TwoThru() TwoThru::TwoThru()
{ {
Z0 = 50.0; Z0 = 50.0;
port1 = 1;
port2 = 2;
} }
void TwoThru::transformDatapoint(VirtualDevice::VNAMeasurement &p) void TwoThru::transformDatapoint(VirtualDevice::VNAMeasurement &p)
{ {
// correct measurement // correct measurement
if(points.size() > 0) { if(points.size() > 0) {
Tparam meas(p.toSparam(1,2)); Tparam meas(p.toSparam(port1,port2));
Tparam inv1, inv2; Tparam inv1, inv2;
if(p.frequency < points.front().freq) { if(p.frequency < points.front().freq) {
@ -49,7 +51,7 @@ void TwoThru::transformDatapoint(VirtualDevice::VNAMeasurement &p)
// perform correction // perform correction
Tparam corrected = inv1*meas*inv2; Tparam corrected = inv1*meas*inv2;
// transform back into S parameters // transform back into S parameters
p.fromSparam(Sparam(corrected), 1, 2); p.fromSparam(Sparam(corrected), port1, port2);
} }
} }
@ -125,6 +127,27 @@ void TwoThru::edit()
ui->Z0->setVisible(false); ui->Z0->setVisible(false);
ui->lZ0->setVisible(false); ui->lZ0->setVisible(false);
ui->port1->setValue(port1);
ui->port1->setMaximum(VirtualDevice::getInfo(VirtualDevice::getConnected()).ports);
ui->port2->setValue(port2);
ui->port2->setMaximum(VirtualDevice::getInfo(VirtualDevice::getConnected()).ports);
auto portChanged = [=](){
port1 = ui->port1->value();
port2 = ui->port2->value();
// clear all points
points.clear();
measurements2xthru.clear();
measurementsDUT.clear();
// enable taking of new measurements only if ports are different
ui->bMeasure->setEnabled(port1 != port2);
ui->bMeasureDUT->setEnabled(port1 != port2);
updateGUI();
};
connect(ui->port1, qOverload<int>(&QSpinBox::valueChanged), portChanged);
connect(ui->port2, qOverload<int>(&QSpinBox::valueChanged), portChanged);
connect(ui->bMeasure, &QPushButton::clicked, [=](){ connect(ui->bMeasure, &QPushButton::clicked, [=](){
measuringDUT = false; measuringDUT = false;
measuring2xthru = true; measuring2xthru = true;
@ -168,6 +191,8 @@ void TwoThru::edit()
nlohmann::json TwoThru::toJSON() nlohmann::json TwoThru::toJSON()
{ {
nlohmann::json j; nlohmann::json j;
j["port1"] = port1;
j["port2"] = port2;
for(auto p : points) { for(auto p : points) {
nlohmann::json jp; nlohmann::json jp;
jp["frequency"] = p.freq; jp["frequency"] = p.freq;
@ -194,6 +219,8 @@ nlohmann::json TwoThru::toJSON()
void TwoThru::fromJSON(nlohmann::json j) void TwoThru::fromJSON(nlohmann::json j)
{ {
port1 = j.value("port1", 1);
port2 = j.value("port2", 2);
points.clear(); points.clear();
for(auto jp : j) { for(auto jp : j) {
Point p; Point p;
@ -229,10 +256,11 @@ std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<VirtualDevi
// ignore possible DC point // ignore possible DC point
continue; continue;
} }
S11.push_back(m.measurements["S11"]); auto S = m.toSparam(port1, port2);
S12.push_back(m.measurements["S12"]); S11.push_back(S.m11);
S21.push_back(m.measurements["S21"]); S12.push_back(S.m12);
S22.push_back(m.measurements["S22"]); S21.push_back(S.m21);
S22.push_back(S.m22);
f.push_back(m.frequency); f.push_back(m.frequency);
} }
auto n = f.size(); auto n = f.size();

View File

@ -33,12 +33,13 @@ private:
}; };
static std::vector<VirtualDevice::VNAMeasurement> interpolateEvenFrequencySteps(std::vector<VirtualDevice::VNAMeasurement> input); static std::vector<VirtualDevice::VNAMeasurement> interpolateEvenFrequencySteps(std::vector<VirtualDevice::VNAMeasurement> input);
static std::vector<Point> calculateErrorBoxes(std::vector<VirtualDevice::VNAMeasurement> data_2xthru); std::vector<Point> calculateErrorBoxes(std::vector<VirtualDevice::VNAMeasurement> data_2xthru);
static std::vector<Point> calculateErrorBoxes(std::vector<VirtualDevice::VNAMeasurement> data_2xthru, std::vector<VirtualDevice::VNAMeasurement> data_fix_dut_fix, double z0); std::vector<Point> calculateErrorBoxes(std::vector<VirtualDevice::VNAMeasurement> data_2xthru, std::vector<VirtualDevice::VNAMeasurement> data_fix_dut_fix, double z0);
std::vector<VirtualDevice::VNAMeasurement> measurements2xthru; std::vector<VirtualDevice::VNAMeasurement> measurements2xthru;
std::vector<VirtualDevice::VNAMeasurement> measurementsDUT; std::vector<VirtualDevice::VNAMeasurement> measurementsDUT;
double Z0; double Z0;
int port1, port2;
std::vector<Point> points; std::vector<Point> points;
bool measuring2xthru; bool measuring2xthru;
bool measuringDUT; bool measuringDUT;

View File

@ -9,8 +9,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>701</width> <width>732</width>
<height>465</height> <height>520</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -19,7 +19,7 @@
<property name="modal"> <property name="modal">
<bool>true</bool> <bool>true</bool>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,0"> <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,0,0">
<item> <item>
<widget class="QGroupBox" name="groupBox_3"> <widget class="QGroupBox" name="groupBox_3">
<property name="title"> <property name="title">
@ -51,6 +51,56 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Configuration</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>2xthru is between ports</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="port1">
<property name="minimum">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>and</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="port2">
<property name="minimum">
<number>1</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="title"> <property name="title">

View File

@ -1,11 +1,14 @@
#include "appwindow.h" #include "appwindow.h"
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
#include "Device/device.h" #include "Device/device.h"
#include "Device/virtualdevice.h"
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
#include <signal.h> #include <signal.h>
#endif #endif
#include "Tools/parameters.h"
#include <complex>
using namespace std;
static QApplication *app; static QApplication *app;
static AppWindow *window; static AppWindow *window;
@ -21,9 +24,6 @@ int main(int argc, char *argv[]) {
qSetMessagePattern("%{time process}: [%{type}] %{message}"); qSetMessagePattern("%{time process}: [%{type}] %{message}");
Device::RegisterTypes();
VirtualDevice::RegisterTypes();
app = new QApplication(argc, argv); app = new QApplication(argc, argv);
QCoreApplication::setOrganizationName("LibreVNA"); QCoreApplication::setOrganizationName("LibreVNA");
QCoreApplication::setApplicationName("LibreVNA-GUI"); QCoreApplication::setApplicationName("LibreVNA-GUI");
@ -31,6 +31,34 @@ int main(int argc, char *argv[]) {
QCoreApplication::setApplicationVersion(window->getAppVersion() + "-" + QCoreApplication::setApplicationVersion(window->getAppVersion() + "-" +
window->getAppGitHash().left(9)); window->getAppGitHash().left(9));
Device::RegisterTypes();
auto S11 = complex<double>(-0.5, 0.25);
auto S22 = complex<double>(0.5, 0.15);
auto S33 = complex<double>(0.8, -0.25);
auto S12 = complex<double>(0.1, 0);
auto S21 = complex<double>(0.2, 0.3);
auto S13 = complex<double>(0.3, -0.2);
auto S31 = complex<double>(0.4, 0.4);
auto S23 = complex<double>(0.5, 0.2);
auto S32 = complex<double>(0.6, -0.2);
auto p12 = Sparam(S11, S12, S21, S22);
auto p12_only = Sparam(0.0, S12, 1.0, 0.0);
auto p13 = Sparam(S11, S13, S31, S33);
auto p23 = Sparam(S22, S23, S32, S33);
// convert to 75 ohm
auto p12_75 = Sparam(ABCDparam(p12, 50.0), 75.0);
auto p12_only_75 = Sparam(ABCDparam(p12_only, 50.0), 75.0);
auto p13_75 = Sparam(ABCDparam(p12, 50.0), 75.0);
auto Zp23_75 = Sparam(ABCDparam(p12, 50.0), 75.0);
auto p1 = Sparam(S11, 0.0, 0.0, 1.0);
auto p1_75 = Sparam(ABCDparam(p12, 50.0), 75.0);
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
signal(SIGINT, tryExitGracefully); signal(SIGINT, tryExitGracefully);

View File

@ -310,6 +310,7 @@ void PreferencesDialog::setInitialGUIState()
ui->MarkerShowAllMarkerData->setChecked(p->Marker.defaultBehavior.showAllData); ui->MarkerShowAllMarkerData->setChecked(p->Marker.defaultBehavior.showAllData);
ui->MarkerInterpolate->setCurrentIndex(p->Marker.interpolatePoints ? 1 : 0); ui->MarkerInterpolate->setCurrentIndex(p->Marker.interpolatePoints ? 1 : 0);
ui->MarkerSortOrder->setCurrentIndex((int) p->Marker.sortOrder); ui->MarkerSortOrder->setCurrentIndex((int) p->Marker.sortOrder);
ui->MarkerSymbolStyle->setCurrentIndex((int) p->Marker.symbolStyle);
ui->SCPIServerEnabled->setChecked(p->SCPIServer.enabled); ui->SCPIServerEnabled->setChecked(p->SCPIServer.enabled);
ui->SCPIServerPort->setValue(p->SCPIServer.port); ui->SCPIServerPort->setValue(p->SCPIServer.port);
@ -380,6 +381,7 @@ void PreferencesDialog::updateFromGUI()
p->Marker.defaultBehavior.showAllData = ui->MarkerShowAllMarkerData->isChecked(); p->Marker.defaultBehavior.showAllData = ui->MarkerShowAllMarkerData->isChecked();
p->Marker.interpolatePoints = ui->MarkerInterpolate->currentIndex() == 1; p->Marker.interpolatePoints = ui->MarkerInterpolate->currentIndex() == 1;
p->Marker.sortOrder = (MarkerSortOrder) ui->MarkerSortOrder->currentIndex(); p->Marker.sortOrder = (MarkerSortOrder) ui->MarkerSortOrder->currentIndex();
p->Marker.symbolStyle = (MarkerSymbolStyle) ui->MarkerSymbolStyle->currentIndex();
p->SCPIServer.enabled = ui->SCPIServerEnabled->isChecked(); p->SCPIServer.enabled = ui->SCPIServerEnabled->isChecked();
p->SCPIServer.port = ui->SCPIServerPort->value(); p->SCPIServer.port = ui->SCPIServerPort->value();

View File

@ -34,6 +34,14 @@ enum MarkerSortOrder {
Q_DECLARE_METATYPE(MarkerSortOrder) Q_DECLARE_METATYPE(MarkerSortOrder)
enum MarkerSymbolStyle {
FilledNumberInside = 0,
FilledNumberAbove = 1,
EmptyNumberAbove = 2,
};
Q_DECLARE_METATYPE(MarkerSymbolStyle);
class Preferences : public Savable { class Preferences : public Savable {
public: public:
@ -126,6 +134,7 @@ public:
} defaultBehavior; } defaultBehavior;
bool interpolatePoints; bool interpolatePoints;
MarkerSortOrder sortOrder; MarkerSortOrder sortOrder;
MarkerSymbolStyle symbolStyle;
} Marker; } Marker;
struct { struct {
bool enabled; bool enabled;
@ -204,6 +213,7 @@ private:
{&Marker.defaultBehavior.showAllData, "Marker.defaultBehavior.ShowAllData", false}, {&Marker.defaultBehavior.showAllData, "Marker.defaultBehavior.ShowAllData", false},
{&Marker.interpolatePoints, "Marker.interpolatePoints", false}, {&Marker.interpolatePoints, "Marker.interpolatePoints", false},
{&Marker.sortOrder, "Marker.sortOrder", MarkerSortOrder::PrefMarkerSortXCoord}, {&Marker.sortOrder, "Marker.sortOrder", MarkerSortOrder::PrefMarkerSortXCoord},
{&Marker.symbolStyle, "Marker.symbolStyle", MarkerSymbolStyle::EmptyNumberAbove},
{&SCPIServer.enabled, "SCPIServer.enabled", true}, {&SCPIServer.enabled, "SCPIServer.enabled", true},
{&SCPIServer.port, "SCPIServer.port", 19542}, {&SCPIServer.port, "SCPIServer.port", 19542},
{&compoundDeviceJSON, "compoundDeviceJSON", "[]"}, {&compoundDeviceJSON, "compoundDeviceJSON", "[]"},

View File

@ -84,7 +84,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>687</width> <width>687</width>
<height>938</height> <height>884</height>
</rect> </rect>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_12"> <layout class="QHBoxLayout" name="horizontalLayout_12">
@ -103,7 +103,7 @@
</size> </size>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="Startup"> <widget class="QWidget" name="Startup">
<layout class="QHBoxLayout" name="horizontalLayout_4"> <layout class="QHBoxLayout" name="horizontalLayout_4">
@ -1286,6 +1286,32 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<widget class="QLabel" name="label_45">
<property name="text">
<string>Symbol Style:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="MarkerSymbolStyle">
<item>
<property name="text">
<string>Filled triangle - Marker number inside</string>
</property>
</item>
<item>
<property name="text">
<string>Filled triangle - Marker number above</string>
</property>
</item>
<item>
<property name="text">
<string>Empty triangle - Marker number above</string>
</property>
</item>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>