de-embed touchstone-defined through

This commit is contained in:
Jan Käberich 2021-11-27 19:11:45 +01:00
parent 914468dbb2
commit 8269fdfa57
18 changed files with 744 additions and 397 deletions

View File

@ -315,7 +315,7 @@ nlohmann::json SpectrumAnalyzer::toJSON()
tracking["enabled"] = settings.trackingGenerator ? true : false;
tracking["port"] = settings.trackingGeneratorPort ? 2 : 1;
tracking["offset"] = settings.trackingGeneratorOffset;
tracking["power"] = settings.trackingPower;
tracking["power"] = (double) settings.trackingPower / 100.0; // convert to dBm
sweep["trackingGenerator"] = tracking;
if(normalize.active) {

View File

@ -1560,7 +1560,7 @@ bool Marker::isMovable()
// helper traces are never movable by the user
return false;
}
if(trace()->size() == 0) {
if(!parentTrace || parentTrace->size() == 0) {
return false;
}
switch(type) {

View File

@ -1,6 +1,8 @@
#include "matchingnetwork.h"
#include "ui_matchingnetworkdialog.h"
#include "unit.h"
#include "CustomWidgets/informationbox.h"
#include <QDialog>
#include <QHBoxLayout>
@ -11,6 +13,7 @@
#include <QMimeData>
#include <algorithm>
#include <QDebug>
#include <QFileDialog>
using namespace std;
@ -83,24 +86,25 @@ void MatchingNetwork::edit()
ui->lParallelC->installEventFilter(this);
ui->lParallelL->installEventFilter(this);
ui->lParallelR->installEventFilter(this);
ui->lDefinedThrough->installEventFilter(this);
layout->setContentsMargins(0,0,0,0);
layout->setSpacing(0);
layout->addStretch(1);
auto p1 = new QWidget();
p1->setMinimumSize(portWidth, 150);
p1->setMaximumSize(portWidth, 150);
p1->setMinimumSize(portWidth, 151);
p1->setMaximumSize(portWidth, 151);
p1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
p1->setStyleSheet("image: url(:/icons/port1.svg);");
p1->setStyleSheet("image: url(:/icons/port1.png);");
auto DUT = new QWidget();
DUT->setMinimumSize(DUTWidth, 150);
DUT->setMaximumSize(DUTWidth, 150);
DUT->setMinimumSize(DUTWidth, 151);
DUT->setMaximumSize(DUTWidth, 151);
DUT->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
DUT->setStyleSheet("image: url(:/icons/DUT.svg);");
DUT->setStyleSheet("image: url(:/icons/DUT.png);");
auto p2 = new QWidget();
p2->setMinimumSize(portWidth, 150);
p2->setMaximumSize(portWidth, 150);
p2->setMinimumSize(portWidth, 151);
p2->setMaximumSize(portWidth, 151);
p2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
p2->setStyleSheet("image: url(:/icons/port2.svg);");
p2->setStyleSheet("image: url(:/icons/port2.png);");
layout->addWidget(p1);
for(auto w : p1Network) {
layout->addWidget(w);
@ -136,27 +140,31 @@ void MatchingNetwork::edit()
nlohmann::json MatchingNetwork::toJSON()
{
nlohmann::json j;
for(int i=0;i<2;i++) {
auto network = i==0 ? p1Network : p2Network;
nlohmann::json jn;
for(auto c : network) {
nlohmann::json jn1, jn2;
for(auto c : p1Network) {
nlohmann::json jc;
jc["component"] = c->getName().toStdString();
jc["params"] = c->toJSON();
jn.push_back(jc);
jn1.push_back(jc);
}
j.push_back(jn);
for(auto c : p2Network) {
nlohmann::json jc;
jc["component"] = c->getName().toStdString();
jc["params"] = c->toJSON();
jn2.push_back(jc);
}
j["port1"] = jn1;
j["port2"] = jn2;
j["addNetwork"] = addNetwork;
return j;
}
void MatchingNetwork::fromJSON(nlohmann::json j)
{
for(int i=0;i<2;i++) {
auto jn = j[i];
auto &network = i==0 ? p1Network : p2Network;
network.clear();
for(auto jc : jn) {
p1Network.clear();
p2Network.clear();
if(j.contains("port1")) {
for(auto jc : j["port1"]) {
if(!jc.contains("component")) {
continue;
}
@ -165,9 +173,23 @@ void MatchingNetwork::fromJSON(nlohmann::json j)
continue;
}
c->fromJSON(jc["params"]);
network.push_back(c);
p1Network.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);
matching.clear();
}
@ -329,8 +351,8 @@ bool MatchingNetwork::eventFilter(QObject *object, QEvent *event)
dropComponent = (MatchingComponent*) dropPtr;
dragEvent->acceptProposedAction();
insertIndicator = new QWidget();
insertIndicator->setMinimumSize(2, 150);
insertIndicator->setMaximumSize(2, 150);
insertIndicator->setMinimumSize(2, imageHeight);
insertIndicator->setMaximumSize(2, imageHeight);
insertIndicator->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
insertIndicator->setStyleSheet("background-color:red;");
updateInsertIndicator(dragEvent->pos().x());
@ -368,6 +390,8 @@ bool MatchingNetwork::eventFilter(QObject *object, QEvent *event)
dragComponent = new MatchingComponent(MatchingComponent::Type::ParallelL);
} else if(object->objectName() == "lParallelR") {
dragComponent = new MatchingComponent(MatchingComponent::Type::ParallelR);
} else if(object->objectName() == "lDefinedThrough") {
dragComponent = new MatchingComponent(MatchingComponent::Type::DefinedThrough);
} else {
dragComponent = nullptr;
}
@ -397,18 +421,21 @@ bool MatchingNetwork::eventFilter(QObject *object, QEvent *event)
MatchingComponent::MatchingComponent(Type type)
{
this->type = type;
setMinimumSize(150, 150);
setMaximumSize(150, 150);
eValue = nullptr;
touchstone = nullptr;
touchstoneLabel = nullptr;
setMinimumSize(151, 151);
setMaximumSize(151, 151);
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
eValue = new SIUnitEdit();
eValue->setPrecision(4);
eValue->setPrefixes("fpnum k");
connect(eValue, &SIUnitEdit::valueChanged, this, &MatchingComponent::valueChanged);
setFocusPolicy(Qt::FocusPolicy::ClickFocus);
switch(type) {
case Type::SeriesR:
case Type::SeriesL:
case Type::SeriesC: {
eValue = new SIUnitEdit();
eValue->setPrecision(4);
eValue->setPrefixes("fpnum k");
connect(eValue, &SIUnitEdit::valueChanged, this, &MatchingComponent::valueChanged);
auto layout = new QVBoxLayout();
layout->addWidget(eValue);
setLayout(layout);
@ -417,13 +444,16 @@ MatchingComponent::MatchingComponent(Type type)
case Type::ParallelR:
case Type::ParallelL:
case Type::ParallelC: {
eValue = new SIUnitEdit();
eValue->setPrecision(4);
eValue->setPrefixes("fpnum k");
connect(eValue, &SIUnitEdit::valueChanged, this, &MatchingComponent::valueChanged);
auto layout = new QVBoxLayout();
layout->addWidget(eValue);
layout->addStretch(1);
layout->setContentsMargins(9, 5, 9, 9);
setLayout(layout);
}
break;
default:
break;
}
@ -431,38 +461,58 @@ MatchingComponent::MatchingComponent(Type type)
case Type::SeriesR:
eValue->setUnit("Ω");
eValue->setValue(50);
setStyleSheet("image: url(:/icons/seriesR.svg);");
setStyleSheet("image: url(:/icons/seriesR.png);");
break;
case Type::SeriesL:
eValue->setUnit("H");
eValue->setValue(1e-9);
setStyleSheet("image: url(:/icons/seriesL.svg);");
setStyleSheet("image: url(:/icons/seriesL.png);");
break;
case Type::SeriesC:
eValue->setUnit("F");
eValue->setValue(1e-12);
setStyleSheet("image: url(:/icons/seriesC.svg);");
setStyleSheet("image: url(:/icons/seriesC.png);");
break;
case Type::ParallelR:
eValue->setUnit("Ω");
eValue->setValue(50);
setStyleSheet("image: url(:/icons/parallelR.svg);");
setStyleSheet("image: url(:/icons/parallelR.png);");
break;
case Type::ParallelL:
eValue->setUnit("H");
eValue->setValue(1e-9);
setStyleSheet("image: url(:/icons/parallelL.svg);");
setStyleSheet("image: url(:/icons/parallelL.png);");
break;
case Type::ParallelC:
eValue->setUnit("F");
eValue->setValue(1e-12);
setStyleSheet("image: url(:/icons/parallelC.svg);");
setStyleSheet("image: url(:/icons/parallelC.png);");
break;
case Type::DefinedThrough: {
touchstone = new Touchstone(2);
touchstoneLabel = new QLabel();
touchstoneLabel->setWordWrap(true);
touchstoneLabel->setAlignment(Qt::AlignCenter);
auto layout = new QVBoxLayout();
layout->addWidget(touchstoneLabel);
layout->setContentsMargins(0, 0, 0, 0);
setLayout(layout);
setStyleSheet("image: url(:/icons/definedThrough.png);");
updateTouchstoneLabel();
}
break;
default:
break;
}
}
MatchingComponent::~MatchingComponent()
{
delete eValue;
delete touchstone;
delete touchstoneLabel;
}
ABCDparam MatchingComponent::parameters(double freq)
{
switch(type) {
@ -478,6 +528,15 @@ ABCDparam MatchingComponent::parameters(double freq)
return ABCDparam(1.0, 0.0, 1.0/complex<double>(0, freq * 2 * M_PI * eValue->value()), 1.0);
case Type::ParallelC:
return ABCDparam(1.0, 0.0, 1.0/complex<double>(0, -1.0 / (freq * 2 * M_PI * eValue->value())), 1.0);
case Type::DefinedThrough:
if(touchstone->points() == 0 || freq < touchstone->minFreq() || freq > touchstone->maxFreq()) {
// outside of provided frequency range, pass through unchanged
return ABCDparam(1.0, 0.0, 0.0, 1.0);
} else {
auto d = touchstone->interpolate(freq);
auto S = Sparam(d.S[0], d.S[1], d.S[2], d.S[3]);
return ABCDparam(S, 50.0);
}
default:
return ABCDparam(1.0, 0.0, 0.0, 1.0);
}
@ -485,7 +544,9 @@ ABCDparam MatchingComponent::parameters(double freq)
void MatchingComponent::MatchingComponent::setValue(double v)
{
if(eValue) {
eValue->setValue(v);
}
}
MatchingComponent *MatchingComponent::createFromName(QString name)
@ -507,13 +568,73 @@ QString MatchingComponent::getName()
nlohmann::json MatchingComponent::toJSON()
{
nlohmann::json j;
switch(type) {
case Type::SeriesC:
case Type::SeriesR:
case Type::SeriesL:
case Type::ParallelC:
case Type::ParallelR:
case Type::ParallelL:
j["value"] = eValue->value();
break;
case Type::DefinedThrough:
j["touchstone"] = touchstone->toJSON();
break;
case Type::Last:
break;
}
return j;
}
void MatchingComponent::fromJSON(nlohmann::json j)
{
switch(type) {
case Type::SeriesC:
case Type::SeriesR:
case Type::SeriesL:
case Type::ParallelC:
case Type::ParallelR:
case Type::ParallelL:
eValue->setValue(j.value("value", 1e-12));
break;
case Type::DefinedThrough:
touchstone->fromJSON(j["touchstone"]);
updateTouchstoneLabel();
break;
case Type::Last:
break;
}
}
void MatchingComponent::mouseDoubleClickEvent(QMouseEvent *e)
{
Q_UNUSED(e);
if(type == Type::DefinedThrough) {
// select new touchstone file
auto filename = QFileDialog::getOpenFileName(nullptr, "Open measurement file", "", "Touchstone files (*.s2p)", nullptr, QFileDialog::DontUseNativeDialog);
if (!filename.isEmpty()) {
try {
*touchstone = Touchstone::fromFile(filename.toStdString());
} catch(const std::exception& e) {
InformationBox::ShowError("Failed to load file", QString("Attempt to load file ended with error: \"") + e.what()+"\"");
}
updateTouchstoneLabel();
}
}
}
void MatchingComponent::updateTouchstoneLabel()
{
if(!touchstone || !touchstoneLabel) {
return;
}
if(touchstone->points() == 0) {
touchstoneLabel->setText("No data. Double-click to select touchstone file");
} else {
QString text = QString::number(touchstone->points()) + " points from "+Unit::ToString(touchstone->minFreq(), "Hz", " kMG", 4)
+ " to "+Unit::ToString(touchstone->maxFreq(), "Hz", " kMG", 4);
touchstoneLabel->setText(text);
}
}
QString MatchingComponent::typeToName(MatchingComponent::Type type)
@ -525,6 +646,7 @@ QString MatchingComponent::typeToName(MatchingComponent::Type type)
case Type::ParallelR: return "ParallelR";
case Type::ParallelL: return "ParallelL";
case Type::ParallelC: return "ParallelC";
case Type::DefinedThrough: return "Touchstone Through";
default: return "";
}
}

View File

@ -5,8 +5,10 @@
#include "deembeddingoption.h"
#include "Tools/parameters.h"
#include "savable.h"
#include "touchstone.h"
#include <QWidget>
#include <QLabel>
#include <vector>
@ -21,11 +23,13 @@ public:
ParallelR,
ParallelL,
ParallelC,
DefinedThrough,
// Add new matching components here, do not explicitly assign values and keep the Last entry at the last position
Last,
};
MatchingComponent(Type type);
~MatchingComponent();
ABCDparam parameters(double freq);
void setValue(double v);
@ -40,7 +44,11 @@ signals:
void deleted(MatchingComponent* m);
protected:
SIUnitEdit *eValue;
Touchstone *touchstone;
QLabel *touchstoneLabel;
private:
void mouseDoubleClickEvent(QMouseEvent *e) override;
void updateTouchstoneLabel();
static QString typeToName(Type type);
Type type;
void keyPressEvent(QKeyEvent *event) override;
@ -62,9 +70,10 @@ public:
nlohmann::json toJSON() override;
void fromJSON(nlohmann::json j) override;
private:
static constexpr int componentWidth = 150;
static constexpr int DUTWidth = 150;
static constexpr int portWidth = 75;
static constexpr int imageHeight = 151;
static constexpr int componentWidth = 151;
static constexpr int DUTWidth = 151;
static constexpr int portWidth = 76;
MatchingComponent *componentAtPosition(int pos);
unsigned int findInsertPosition(int xcoord);
void addComponentAtPosition(int pos, MatchingComponent *c);

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>772</width>
<height>442</height>
<height>443</height>
</rect>
</property>
<property name="windowTitle">
@ -131,20 +131,8 @@
<property name="title">
<string>Matching Components</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_9">
<property name="font">
<font>
@ -159,9 +147,7 @@
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<item row="1" column="0">
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@ -219,7 +205,7 @@
</layout>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="1">
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@ -277,7 +263,7 @@
</layout>
</widget>
</item>
<item row="0" column="2">
<item row="1" column="2">
<widget class="QFrame" name="frame_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@ -335,7 +321,65 @@
</layout>
</widget>
</item>
<item row="1" column="0">
<item row="1" column="3">
<widget class="QFrame" name="frame_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>80</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="lDefinedThrough">
<property name="styleSheet">
<string notr="true">border-image: url(:/icons/definedThrough.svg);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;br/&gt;&lt;br/&gt;Defined&lt;br/&gt;Through&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QFrame" name="frame_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@ -399,7 +443,7 @@
</layout>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QFrame" name="frame_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@ -463,7 +507,7 @@
</layout>
</widget>
</item>
<item row="1" column="2">
<item row="2" column="2">
<widget class="QFrame" name="frame_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@ -522,8 +566,6 @@
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>

View File

@ -50,5 +50,13 @@
<file>icons/down.png</file>
<file>icons/up.png</file>
<file>icons/chainlink.png</file>
<file>icons/definedThrough.svg</file>
<file>icons/seriesR.png</file>
<file>icons/seriesL.png</file>
<file>icons/seriesC.png</file>
<file>icons/parallelR.png</file>
<file>icons/parallelL.png</file>
<file>icons/parallelC.png</file>
<file>icons/definedThrough.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 B

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="113.386pt" height="113.386pt" viewBox="0 0 113.386 113.386" version="1.1">
<defs>
<g>
<symbol overflow="visible" id="glyph0-0">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph0-1">
<path style="stroke:none;" d="M 1.90625 -0.53125 C 1.90625 -0.8125 1.671875 -1.0625 1.390625 -1.0625 C 1.09375 -1.0625 0.859375 -0.8125 0.859375 -0.53125 C 0.859375 -0.234375 1.09375 0 1.390625 0 C 1.671875 0 1.90625 -0.234375 1.90625 -0.53125 Z M 1.90625 -0.53125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-2">
<path style="stroke:none;" d="M 3.890625 -3.734375 C 3.625 -3.71875 3.421875 -3.5 3.421875 -3.28125 C 3.421875 -3.140625 3.515625 -2.984375 3.734375 -2.984375 C 3.953125 -2.984375 4.1875 -3.15625 4.1875 -3.546875 C 4.1875 -4 3.765625 -4.40625 3 -4.40625 C 1.6875 -4.40625 1.3125 -3.390625 1.3125 -2.953125 C 1.3125 -2.171875 2.046875 -2.03125 2.34375 -1.96875 C 2.859375 -1.859375 3.375 -1.75 3.375 -1.203125 C 3.375 -0.953125 3.15625 -0.109375 1.953125 -0.109375 C 1.8125 -0.109375 1.046875 -0.109375 0.8125 -0.640625 C 1.203125 -0.59375 1.453125 -0.890625 1.453125 -1.171875 C 1.453125 -1.390625 1.28125 -1.515625 1.078125 -1.515625 C 0.8125 -1.515625 0.515625 -1.3125 0.515625 -0.859375 C 0.515625 -0.296875 1.09375 0.109375 1.9375 0.109375 C 3.5625 0.109375 3.953125 -1.09375 3.953125 -1.546875 C 3.953125 -1.90625 3.765625 -2.15625 3.640625 -2.265625 C 3.375 -2.546875 3.078125 -2.609375 2.640625 -2.6875 C 2.28125 -2.765625 1.890625 -2.84375 1.890625 -3.296875 C 1.890625 -3.578125 2.125 -4.1875 3 -4.1875 C 3.25 -4.1875 3.75 -4.109375 3.890625 -3.734375 Z M 3.890625 -3.734375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-3">
<path style="stroke:none;" d="M 0.453125 1.21875 C 0.375 1.5625 0.34375 1.625 -0.09375 1.625 C -0.203125 1.625 -0.3125 1.625 -0.3125 1.8125 C -0.3125 1.890625 -0.265625 1.9375 -0.1875 1.9375 C 0.078125 1.9375 0.375 1.90625 0.640625 1.90625 C 0.984375 1.90625 1.3125 1.9375 1.640625 1.9375 C 1.6875 1.9375 1.8125 1.9375 1.8125 1.734375 C 1.8125 1.625 1.71875 1.625 1.578125 1.625 C 1.078125 1.625 1.078125 1.5625 1.078125 1.46875 C 1.078125 1.34375 1.5 -0.28125 1.5625 -0.53125 C 1.6875 -0.234375 1.96875 0.109375 2.484375 0.109375 C 3.640625 0.109375 4.890625 -1.34375 4.890625 -2.8125 C 4.890625 -3.75 4.3125 -4.40625 3.5625 -4.40625 C 3.0625 -4.40625 2.578125 -4.046875 2.25 -3.65625 C 2.15625 -4.203125 1.71875 -4.40625 1.359375 -4.40625 C 0.890625 -4.40625 0.703125 -4.015625 0.625 -3.84375 C 0.4375 -3.5 0.3125 -2.90625 0.3125 -2.875 C 0.3125 -2.765625 0.40625 -2.765625 0.421875 -2.765625 C 0.53125 -2.765625 0.53125 -2.78125 0.59375 -3 C 0.765625 -3.703125 0.96875 -4.1875 1.328125 -4.1875 C 1.5 -4.1875 1.640625 -4.109375 1.640625 -3.734375 C 1.640625 -3.5 1.609375 -3.390625 1.5625 -3.21875 Z M 2.203125 -3.109375 C 2.265625 -3.375 2.546875 -3.65625 2.71875 -3.8125 C 3.078125 -4.109375 3.359375 -4.1875 3.53125 -4.1875 C 3.921875 -4.1875 4.171875 -3.84375 4.171875 -3.25 C 4.171875 -2.65625 3.84375 -1.515625 3.65625 -1.140625 C 3.3125 -0.4375 2.84375 -0.109375 2.46875 -0.109375 C 1.8125 -0.109375 1.6875 -0.9375 1.6875 -1 C 1.6875 -1.015625 1.6875 -1.03125 1.71875 -1.15625 Z M 2.203125 -3.109375 "/>
</symbol>
<symbol overflow="visible" id="glyph1-0">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph1-1">
<path style="stroke:none;" d="M 1.265625 -0.765625 L 2.328125 -1.796875 C 3.875 -3.171875 4.46875 -3.703125 4.46875 -4.703125 C 4.46875 -5.84375 3.578125 -6.640625 2.359375 -6.640625 C 1.234375 -6.640625 0.5 -5.71875 0.5 -4.828125 C 0.5 -4.28125 1 -4.28125 1.03125 -4.28125 C 1.203125 -4.28125 1.546875 -4.390625 1.546875 -4.8125 C 1.546875 -5.0625 1.359375 -5.328125 1.015625 -5.328125 C 0.9375 -5.328125 0.921875 -5.328125 0.890625 -5.3125 C 1.109375 -5.96875 1.65625 -6.328125 2.234375 -6.328125 C 3.140625 -6.328125 3.5625 -5.515625 3.5625 -4.703125 C 3.5625 -3.90625 3.078125 -3.125 2.515625 -2.5 L 0.609375 -0.375 C 0.5 -0.265625 0.5 -0.234375 0.5 0 L 4.203125 0 L 4.46875 -1.734375 L 4.234375 -1.734375 C 4.171875 -1.4375 4.109375 -1 4 -0.84375 C 3.9375 -0.765625 3.28125 -0.765625 3.0625 -0.765625 Z M 1.265625 -0.765625 "/>
</symbol>
</g>
<clipPath id="clip1">
<path d="M 0 28 L 113.386719 28 L 113.386719 29 L 0 29 Z M 0 28 "/>
</clipPath>
</defs>
<g id="surface1">
<g clip-path="url(#clip1)" clip-rule="nonzero">
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 0 85.04225 L 40.820312 85.04225 M 72.566406 85.04225 L 113.386719 85.04225 " transform="matrix(1,0,0,-1,0,113.386)"/>
</g>
<path style="fill:none;stroke-width:0.797;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 40.820312 90.991469 L 72.566406 90.991469 L 72.566406 79.089125 L 40.820312 79.089125 Z M 40.820312 90.991469 " transform="matrix(1,0,0,-1,0,113.386)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="47.977" y="30.588"/>
<use xlink:href="#glyph0-2" x="50.74461" y="30.588"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-1" x="55.415" y="30.588"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-3" x="60.396" y="30.588"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,6 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="56.693pt" height="113.386pt" viewBox="0 0 56.693 113.386" version="1.1">
<defs>
<g>
<symbol overflow="visible" id="glyph0-0">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph0-1">
<path style="stroke:none;" d="M 2.265625 -3.15625 L 3.953125 -3.15625 C 5.140625 -3.15625 6.21875 -3.953125 6.21875 -4.953125 C 6.21875 -5.9375 5.234375 -6.8125 3.875 -6.8125 L 0.34375 -6.8125 L 0.34375 -6.5 L 0.59375 -6.5 C 1.359375 -6.5 1.375 -6.390625 1.375 -6.03125 L 1.375 -0.78125 C 1.375 -0.421875 1.359375 -0.3125 0.59375 -0.3125 L 0.34375 -0.3125 L 0.34375 0 C 0.703125 -0.03125 1.4375 -0.03125 1.8125 -0.03125 C 2.1875 -0.03125 2.9375 -0.03125 3.296875 0 L 3.296875 -0.3125 L 3.046875 -0.3125 C 2.28125 -0.3125 2.265625 -0.421875 2.265625 -0.78125 Z M 2.234375 -3.40625 L 2.234375 -6.09375 C 2.234375 -6.4375 2.25 -6.5 2.71875 -6.5 L 3.609375 -6.5 C 5.1875 -6.5 5.1875 -5.4375 5.1875 -4.953125 C 5.1875 -4.484375 5.1875 -3.40625 3.609375 -3.40625 Z M 2.234375 -3.40625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-2">
<path style="stroke:none;" d="M 4.6875 -2.140625 C 4.6875 -3.40625 3.703125 -4.46875 2.5 -4.46875 C 1.25 -4.46875 0.28125 -3.375 0.28125 -2.140625 C 0.28125 -0.84375 1.3125 0.109375 2.484375 0.109375 C 3.6875 0.109375 4.6875 -0.875 4.6875 -2.140625 Z M 2.5 -0.140625 C 2.0625 -0.140625 1.625 -0.34375 1.359375 -0.8125 C 1.109375 -1.25 1.109375 -1.859375 1.109375 -2.21875 C 1.109375 -2.609375 1.109375 -3.140625 1.34375 -3.578125 C 1.609375 -4.03125 2.078125 -4.25 2.484375 -4.25 C 2.921875 -4.25 3.34375 -4.03125 3.609375 -3.59375 C 3.875 -3.171875 3.875 -2.59375 3.875 -2.21875 C 3.875 -1.859375 3.875 -1.3125 3.65625 -0.875 C 3.421875 -0.421875 2.984375 -0.140625 2.5 -0.140625 Z M 2.5 -0.140625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-3">
<path style="stroke:none;" d="M 1.671875 -3.3125 L 1.671875 -4.40625 L 0.28125 -4.296875 L 0.28125 -3.984375 C 0.984375 -3.984375 1.0625 -3.921875 1.0625 -3.421875 L 1.0625 -0.75 C 1.0625 -0.3125 0.953125 -0.3125 0.28125 -0.3125 L 0.28125 0 C 0.671875 -0.015625 1.140625 -0.03125 1.421875 -0.03125 C 1.8125 -0.03125 2.28125 -0.03125 2.6875 0 L 2.6875 -0.3125 L 2.46875 -0.3125 C 1.734375 -0.3125 1.71875 -0.421875 1.71875 -0.78125 L 1.71875 -2.3125 C 1.71875 -3.296875 2.140625 -4.1875 2.890625 -4.1875 C 2.953125 -4.1875 2.984375 -4.1875 3 -4.171875 C 2.96875 -4.171875 2.765625 -4.046875 2.765625 -3.78125 C 2.765625 -3.515625 2.984375 -3.359375 3.203125 -3.359375 C 3.375 -3.359375 3.625 -3.484375 3.625 -3.796875 C 3.625 -4.109375 3.3125 -4.40625 2.890625 -4.40625 C 2.15625 -4.40625 1.796875 -3.734375 1.671875 -3.3125 Z M 1.671875 -3.3125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-4">
<path style="stroke:none;" d="M 1.71875 -3.984375 L 3.15625 -3.984375 L 3.15625 -4.296875 L 1.71875 -4.296875 L 1.71875 -6.125 L 1.46875 -6.125 C 1.46875 -5.3125 1.171875 -4.25 0.1875 -4.203125 L 0.1875 -3.984375 L 1.03125 -3.984375 L 1.03125 -1.234375 C 1.03125 -0.015625 1.96875 0.109375 2.328125 0.109375 C 3.03125 0.109375 3.3125 -0.59375 3.3125 -1.234375 L 3.3125 -1.796875 L 3.0625 -1.796875 L 3.0625 -1.25 C 3.0625 -0.515625 2.765625 -0.140625 2.390625 -0.140625 C 1.71875 -0.140625 1.71875 -1.046875 1.71875 -1.21875 Z M 1.71875 -3.984375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-5">
<path style="stroke:none;" d="M 2.9375 -6.375 C 2.9375 -6.625 2.9375 -6.640625 2.703125 -6.640625 C 2.078125 -6 1.203125 -6 0.890625 -6 L 0.890625 -5.6875 C 1.09375 -5.6875 1.671875 -5.6875 2.1875 -5.953125 L 2.1875 -0.78125 C 2.1875 -0.421875 2.15625 -0.3125 1.265625 -0.3125 L 0.953125 -0.3125 L 0.953125 0 C 1.296875 -0.03125 2.15625 -0.03125 2.5625 -0.03125 C 2.953125 -0.03125 3.828125 -0.03125 4.171875 0 L 4.171875 -0.3125 L 3.859375 -0.3125 C 2.953125 -0.3125 2.9375 -0.421875 2.9375 -0.78125 Z M 2.9375 -6.375 "/>
</symbol>
</g>
<clipPath id="clip1">
<path d="M 28 28 L 56.691406 28 L 56.691406 29 L 28 29 Z M 28 28 "/>
</clipPath>
@ -12,6 +32,17 @@
<g clip-path="url(#clip1)" clip-rule="nonzero">
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 28.347656 85.04225 L 56.695312 85.04225 " transform="matrix(1,0,0,-1,0,113.386)"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="10.597" y="20.975"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-2" x="17.098593" y="20.975"/>
<use xlink:href="#glyph0-3" x="22.079893" y="20.975"/>
<use xlink:href="#glyph0-4" x="25.982243" y="20.975"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-5" x="33.174244" y="20.975"/>
</g>
<g clip-path="url(#clip2)" clip-rule="nonzero">
<path style="fill:none;stroke-width:0.797;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 28.347656 85.04225 C 28.347656 87.233656 26.570312 89.007094 24.378906 89.007094 C 22.1875 89.007094 20.410156 87.233656 20.410156 85.04225 C 20.410156 82.850844 22.1875 81.0735 24.378906 81.0735 C 26.570312 81.0735 28.347656 82.850844 28.347656 85.04225 Z M 28.347656 85.04225 " transform="matrix(1,0,0,-1,0,113.386)"/>
</g>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -1,12 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="56.693pt" height="113.386pt" viewBox="0 0 56.693 113.386" version="1.1">
<defs>
<g>
<symbol overflow="visible" id="glyph0-0">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph0-1">
<path style="stroke:none;" d="M 2.265625 -3.15625 L 3.953125 -3.15625 C 5.140625 -3.15625 6.21875 -3.953125 6.21875 -4.953125 C 6.21875 -5.9375 5.234375 -6.8125 3.875 -6.8125 L 0.34375 -6.8125 L 0.34375 -6.5 L 0.59375 -6.5 C 1.359375 -6.5 1.375 -6.390625 1.375 -6.03125 L 1.375 -0.78125 C 1.375 -0.421875 1.359375 -0.3125 0.59375 -0.3125 L 0.34375 -0.3125 L 0.34375 0 C 0.703125 -0.03125 1.4375 -0.03125 1.8125 -0.03125 C 2.1875 -0.03125 2.9375 -0.03125 3.296875 0 L 3.296875 -0.3125 L 3.046875 -0.3125 C 2.28125 -0.3125 2.265625 -0.421875 2.265625 -0.78125 Z M 2.234375 -3.40625 L 2.234375 -6.09375 C 2.234375 -6.4375 2.25 -6.5 2.71875 -6.5 L 3.609375 -6.5 C 5.1875 -6.5 5.1875 -5.4375 5.1875 -4.953125 C 5.1875 -4.484375 5.1875 -3.40625 3.609375 -3.40625 Z M 2.234375 -3.40625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-2">
<path style="stroke:none;" d="M 4.6875 -2.140625 C 4.6875 -3.40625 3.703125 -4.46875 2.5 -4.46875 C 1.25 -4.46875 0.28125 -3.375 0.28125 -2.140625 C 0.28125 -0.84375 1.3125 0.109375 2.484375 0.109375 C 3.6875 0.109375 4.6875 -0.875 4.6875 -2.140625 Z M 2.5 -0.140625 C 2.0625 -0.140625 1.625 -0.34375 1.359375 -0.8125 C 1.109375 -1.25 1.109375 -1.859375 1.109375 -2.21875 C 1.109375 -2.609375 1.109375 -3.140625 1.34375 -3.578125 C 1.609375 -4.03125 2.078125 -4.25 2.484375 -4.25 C 2.921875 -4.25 3.34375 -4.03125 3.609375 -3.59375 C 3.875 -3.171875 3.875 -2.59375 3.875 -2.21875 C 3.875 -1.859375 3.875 -1.3125 3.65625 -0.875 C 3.421875 -0.421875 2.984375 -0.140625 2.5 -0.140625 Z M 2.5 -0.140625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-3">
<path style="stroke:none;" d="M 1.671875 -3.3125 L 1.671875 -4.40625 L 0.28125 -4.296875 L 0.28125 -3.984375 C 0.984375 -3.984375 1.0625 -3.921875 1.0625 -3.421875 L 1.0625 -0.75 C 1.0625 -0.3125 0.953125 -0.3125 0.28125 -0.3125 L 0.28125 0 C 0.671875 -0.015625 1.140625 -0.03125 1.421875 -0.03125 C 1.8125 -0.03125 2.28125 -0.03125 2.6875 0 L 2.6875 -0.3125 L 2.46875 -0.3125 C 1.734375 -0.3125 1.71875 -0.421875 1.71875 -0.78125 L 1.71875 -2.3125 C 1.71875 -3.296875 2.140625 -4.1875 2.890625 -4.1875 C 2.953125 -4.1875 2.984375 -4.1875 3 -4.171875 C 2.96875 -4.171875 2.765625 -4.046875 2.765625 -3.78125 C 2.765625 -3.515625 2.984375 -3.359375 3.203125 -3.359375 C 3.375 -3.359375 3.625 -3.484375 3.625 -3.796875 C 3.625 -4.109375 3.3125 -4.40625 2.890625 -4.40625 C 2.15625 -4.40625 1.796875 -3.734375 1.671875 -3.3125 Z M 1.671875 -3.3125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-4">
<path style="stroke:none;" d="M 1.71875 -3.984375 L 3.15625 -3.984375 L 3.15625 -4.296875 L 1.71875 -4.296875 L 1.71875 -6.125 L 1.46875 -6.125 C 1.46875 -5.3125 1.171875 -4.25 0.1875 -4.203125 L 0.1875 -3.984375 L 1.03125 -3.984375 L 1.03125 -1.234375 C 1.03125 -0.015625 1.96875 0.109375 2.328125 0.109375 C 3.03125 0.109375 3.3125 -0.59375 3.3125 -1.234375 L 3.3125 -1.796875 L 3.0625 -1.796875 L 3.0625 -1.25 C 3.0625 -0.515625 2.765625 -0.140625 2.390625 -0.140625 C 1.71875 -0.140625 1.71875 -1.046875 1.71875 -1.21875 Z M 1.71875 -3.984375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-5">
<path style="stroke:none;" d="M 1.265625 -0.765625 L 2.328125 -1.796875 C 3.875 -3.171875 4.46875 -3.703125 4.46875 -4.703125 C 4.46875 -5.84375 3.578125 -6.640625 2.359375 -6.640625 C 1.234375 -6.640625 0.5 -5.71875 0.5 -4.828125 C 0.5 -4.28125 1 -4.28125 1.03125 -4.28125 C 1.203125 -4.28125 1.546875 -4.390625 1.546875 -4.8125 C 1.546875 -5.0625 1.359375 -5.328125 1.015625 -5.328125 C 0.9375 -5.328125 0.921875 -5.328125 0.890625 -5.3125 C 1.109375 -5.96875 1.65625 -6.328125 2.234375 -6.328125 C 3.140625 -6.328125 3.5625 -5.515625 3.5625 -4.703125 C 3.5625 -3.90625 3.078125 -3.125 2.515625 -2.5 L 0.609375 -0.375 C 0.5 -0.265625 0.5 -0.234375 0.5 0 L 4.203125 0 L 4.46875 -1.734375 L 4.234375 -1.734375 C 4.171875 -1.4375 4.109375 -1 4 -0.84375 C 3.9375 -0.765625 3.28125 -0.765625 3.0625 -0.765625 Z M 1.265625 -0.765625 "/>
</symbol>
</g>
<clipPath id="clip1">
<path d="M 24.378906 20.410156 L 40.25 20.410156 L 40.25 26.757812 L 24.378906 26.757812 Z M 33.902344 26.757812 L 40.25 26.757812 L 40.25 29.933594 L 33.902344 29.933594 Z M 24.378906 29.933594 L 40.25 29.933594 L 40.25 36.28125 L 24.378906 36.28125 Z M 24.378906 29.933594 "/>
</clipPath>
</defs>
<g id="surface1">
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 28.347656 85.04225 L 0 85.04225 " transform="matrix(1,0,0,-1,0,113.386)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="18.533" y="20.975"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-2" x="25.034593" y="20.975"/>
<use xlink:href="#glyph0-3" x="30.015893" y="20.975"/>
<use xlink:href="#glyph0-4" x="33.918243" y="20.975"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-5" x="41.120207" y="20.975"/>
</g>
<g clip-path="url(#clip1)" clip-rule="nonzero">
<path style="fill:none;stroke-width:0.797;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 28.347656 85.04225 C 28.347656 87.233656 30.125 89.007094 32.316406 89.007094 C 34.507812 89.007094 36.28125 87.233656 36.28125 85.04225 C 36.28125 82.850844 34.507812 81.0735 32.316406 81.0735 C 30.125 81.0735 28.347656 82.850844 28.347656 85.04225 Z M 28.347656 85.04225 " transform="matrix(1,0,0,-1,0,113.386)"/>
</g>

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 759 B

View File

@ -384,3 +384,57 @@ QString Touchstone::getFilename() const
{
return filename;
}
nlohmann::json Touchstone::toJSON()
{
nlohmann::json j;
j["ports"] = m_ports;
j["filename"] = filename.toStdString();
if(m_datapoints.size() > 0) {
nlohmann::json json_points;
for(auto d : m_datapoints) {
nlohmann::json point;
point["frequency"] = d.frequency;
nlohmann::json sparams;
for(auto s : d.S) {
nlohmann::json sparam;
sparam["real"] = s.real();
sparam["imag"] = s.imag();
sparams.push_back(sparam);
}
point["Sparams"] = sparams;
json_points.push_back(point);
}
j["datapoints"] = json_points;
}
return j;
}
void Touchstone::fromJSON(nlohmann::json j)
{
m_datapoints.clear();
filename = QString::fromStdString(j.value("filename", ""));
m_ports = j.value("ports", 0);
if(!m_ports || !j.contains("datapoints")) {
return;
}
auto json_points = j["datapoints"];
for(auto point : json_points) {
Datapoint d;
if(!point.contains("frequency") || !point.contains("Sparams")) {
// missing data, abort here
qWarning() << "Touchstone data point does not contain frequency or S parameters";
break;
}
d.frequency = point["frequency"];
if(point["Sparams"].size() != m_ports * m_ports) {
// invalid number of Sparams, abort here
qWarning() << "Invalid number of S parameters, got" << point["Sparams"].size() << "expected" << m_ports*m_ports;
break;
}
for(auto Sparam : point["Sparams"]) {
d.S.push_back(complex<double>(Sparam.value("real", 0.0), Sparam.value("imag", 0.0)));
}
m_datapoints.push_back(d);
}
}

View File

@ -1,12 +1,14 @@
#ifndef TOUCHSTONE_H
#define TOUCHSTONE_H
#include "savable.h"
#include <complex>
#include <vector>
#include <string>
#include <QString>
class Touchstone
class Touchstone : public Savable
{
public:
enum class Scale {
@ -29,6 +31,7 @@ public:
};
Touchstone(unsigned int m_ports);
virtual ~Touchstone(){};
void AddDatapoint(Datapoint p);
void toFile(std::string filename, Scale unit = Scale::GHz, Format format = Format::RealImaginary);
std::stringstream toString(Scale unit = Scale::GHz, Format format = Format::RealImaginary);
@ -45,6 +48,9 @@ public:
unsigned int ports() { return m_ports; }
QString getFilename() const;
virtual nlohmann::json toJSON();
virtual void fromJSON(nlohmann::json j);
private:
unsigned int m_ports;
std::vector<Datapoint> m_datapoints;