Fix reference impedance for de-embedding traces
This commit is contained in:
parent
3cf37d17b1
commit
77f73d3e05
@ -7,11 +7,11 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>597</width>
|
<width>597</width>
|
||||||
<height>200</height>
|
<height>331</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>Manual Calibration</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -2,21 +2,27 @@
|
|||||||
|
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QScrollBar>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
SparamTraceSelector::SparamTraceSelector(const TraceModel &model, std::vector<unsigned int> used_ports, bool empty_allowed)
|
SparamTraceSelector::SparamTraceSelector(const TraceModel &model, std::vector<unsigned int> used_ports, bool empty_allowed, unsigned int editablePorts)
|
||||||
: model(model),
|
: model(model),
|
||||||
empty_allowed(empty_allowed),
|
empty_allowed(empty_allowed),
|
||||||
used_ports(used_ports)
|
used_ports(used_ports),
|
||||||
|
editablePorts(editablePorts)
|
||||||
{
|
{
|
||||||
createGUI();
|
createGUI();
|
||||||
setInitialChoices();
|
setInitialChoices();
|
||||||
}
|
}
|
||||||
|
|
||||||
SparamTraceSelector::SparamTraceSelector(const TraceModel &model, std::set<unsigned int> used_ports, bool empty_allowed)
|
SparamTraceSelector::SparamTraceSelector(const TraceModel &model, std::set<unsigned int> used_ports, bool empty_allowed, unsigned int editablePorts)
|
||||||
: model(model),
|
: model(model),
|
||||||
empty_allowed(empty_allowed)
|
empty_allowed(empty_allowed),
|
||||||
|
editablePorts(editablePorts)
|
||||||
{
|
{
|
||||||
// create vector from set
|
// create vector from set
|
||||||
std::copy(used_ports.begin(), used_ports.end(), std::back_inserter(this->used_ports));
|
std::copy(used_ports.begin(), used_ports.end(), std::back_inserter(this->used_ports));
|
||||||
@ -113,7 +119,9 @@ void SparamTraceSelector::traceSelectionChanged(QComboBox *cb)
|
|||||||
for(int j=0;j<b->count();j++) {
|
for(int j=0;j<b->count();j++) {
|
||||||
auto candidate = b->itemText(j);
|
auto candidate = b->itemText(j);
|
||||||
// check if correct parameter
|
// check if correct parameter
|
||||||
QString expectedSparam = QString::number(i/used_ports.size()+1)+QString::number(i%used_ports.size()+1);
|
int port1 = used_ports[i/used_ports.size()];
|
||||||
|
int port2 = used_ports[i%used_ports.size()];
|
||||||
|
QString expectedSparam = QString::number(port1)+QString::number(port2);
|
||||||
if(!candidate.endsWith(expectedSparam)) {
|
if(!candidate.endsWith(expectedSparam)) {
|
||||||
// wrong S parameter, skip
|
// wrong S parameter, skip
|
||||||
continue;
|
continue;
|
||||||
@ -131,7 +139,9 @@ void SparamTraceSelector::traceSelectionChanged(QComboBox *cb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if(cb->currentIndex() == 0 && points > 0) {
|
} else if(cb->currentIndex() == 0 && points > 0) {
|
||||||
emit selectionValid(false);
|
if(!empty_allowed) {
|
||||||
|
emit selectionValid(false);
|
||||||
|
}
|
||||||
// Check if all trace selections are set for none
|
// Check if all trace selections are set for none
|
||||||
for(auto c : boxes) {
|
for(auto c : boxes) {
|
||||||
if(!c->isVisible()) {
|
if(!c->isVisible()) {
|
||||||
@ -150,8 +160,8 @@ void SparamTraceSelector::traceSelectionChanged(QComboBox *cb)
|
|||||||
setInitialChoices();
|
setInitialChoices();
|
||||||
}
|
}
|
||||||
if(empty_allowed) {
|
if(empty_allowed) {
|
||||||
// always valid
|
// always valid as soon as at least one trace is selected
|
||||||
emit selectionValid(true);
|
emit selectionValid(points > 0);
|
||||||
} else {
|
} else {
|
||||||
// actually need to check
|
// actually need to check
|
||||||
valid = true;
|
valid = true;
|
||||||
@ -172,8 +182,44 @@ void SparamTraceSelector::traceSelectionChanged(QComboBox *cb)
|
|||||||
void SparamTraceSelector::createGUI()
|
void SparamTraceSelector::createGUI()
|
||||||
{
|
{
|
||||||
// Create comboboxes
|
// Create comboboxes
|
||||||
auto layout = new QFormLayout;
|
qDeleteAll(findChildren<QWidget *>(QString(), Qt::FindDirectChildrenOnly));
|
||||||
setLayout(layout);
|
delete layout();
|
||||||
|
boxes.clear();
|
||||||
|
|
||||||
|
auto scroll = new QScrollArea(this);
|
||||||
|
scroll->installEventFilter(this);
|
||||||
|
scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
auto w = new QWidget();
|
||||||
|
|
||||||
|
auto boxlayout = new QVBoxLayout();
|
||||||
|
setLayout(boxlayout);
|
||||||
|
boxlayout->setContentsMargins(0,0,0,0);
|
||||||
|
boxlayout->addWidget(scroll);
|
||||||
|
|
||||||
|
auto formlayout = new QFormLayout;
|
||||||
|
w->setLayout(formlayout);
|
||||||
|
|
||||||
|
for(unsigned int i=1;i<=editablePorts;i++) {
|
||||||
|
auto label = new QLabel("Include Port "+QString::number(i)+":");
|
||||||
|
auto cb = new QCheckBox();
|
||||||
|
if(std::find(used_ports.begin(), used_ports.end(), i) != used_ports.end()) {
|
||||||
|
cb->setChecked(true);
|
||||||
|
}
|
||||||
|
connect(cb, &QCheckBox::toggled, [=](bool checked){
|
||||||
|
if(checked) {
|
||||||
|
// add this port to the vector at the correct position
|
||||||
|
used_ports.insert(upper_bound(used_ports.begin(), used_ports.end(), i), i);
|
||||||
|
} else {
|
||||||
|
// remove port from the vector
|
||||||
|
used_ports.erase(std::remove(used_ports.begin(), used_ports.end(), i), used_ports.end());
|
||||||
|
}
|
||||||
|
QTimer::singleShot(0, [=](){
|
||||||
|
createGUI();
|
||||||
|
setInitialChoices();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
formlayout->addRow(label, cb);
|
||||||
|
}
|
||||||
for(unsigned int i=0;i<used_ports.size();i++) {
|
for(unsigned int i=0;i<used_ports.size();i++) {
|
||||||
for(unsigned int j=0;j<used_ports.size();j++) {
|
for(unsigned int j=0;j<used_ports.size();j++) {
|
||||||
auto label = new QLabel("S"+QString::number(used_ports[i])+QString::number(used_ports[j])+":");
|
auto label = new QLabel("S"+QString::number(used_ports[i])+QString::number(used_ports[j])+":");
|
||||||
@ -182,7 +228,26 @@ void SparamTraceSelector::createGUI()
|
|||||||
traceSelectionChanged(box);
|
traceSelectionChanged(box);
|
||||||
});
|
});
|
||||||
boxes.push_back(box);
|
boxes.push_back(box);
|
||||||
layout->addRow(label, box);
|
formlayout->addRow(label, box);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scroll->setWidget(w);
|
||||||
|
w->show();
|
||||||
|
eventFilter(scroll, new QEvent(QEvent::Resize));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SparamTraceSelector::eventFilter(QObject *watched, QEvent *event)
|
||||||
|
{
|
||||||
|
// Make sure that the widget in the scroll area always expands to the scroll area size horizontally (only vertical scrolling)
|
||||||
|
if(event->type() == QEvent::Resize) {
|
||||||
|
auto scroll = (QScrollArea*) watched;
|
||||||
|
auto w = scroll->widget();
|
||||||
|
auto width = scroll->width();
|
||||||
|
if(scroll->verticalScrollBar()->isVisible()) {
|
||||||
|
width -= scroll->verticalScrollBar()->width();
|
||||||
|
}
|
||||||
|
w->setFixedWidth(width);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ class SparamTraceSelector : public QWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SparamTraceSelector(const TraceModel &model, std::vector<unsigned int> used_ports, bool empty_allowed = false);
|
SparamTraceSelector(const TraceModel &model, std::vector<unsigned int> used_ports, bool empty_allowed = false, unsigned int editablePorts = 0);
|
||||||
SparamTraceSelector(const TraceModel &model, std::set<unsigned int> used_ports, bool empty_allowed = false);
|
SparamTraceSelector(const TraceModel &model, std::set<unsigned int> used_ports, bool empty_allowed = false, unsigned int editablePorts = 0);
|
||||||
|
|
||||||
bool isValid();
|
bool isValid();
|
||||||
|
|
||||||
@ -29,11 +29,14 @@ private:
|
|||||||
void traceSelectionChanged(QComboBox *cb);
|
void traceSelectionChanged(QComboBox *cb);
|
||||||
void createGUI();
|
void createGUI();
|
||||||
|
|
||||||
|
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
|
|
||||||
const TraceModel &model;
|
const TraceModel &model;
|
||||||
std::vector<QComboBox*> boxes;
|
std::vector<QComboBox*> boxes;
|
||||||
bool empty_allowed;
|
bool empty_allowed;
|
||||||
|
|
||||||
std::vector<unsigned int> used_ports;
|
std::vector<unsigned int> used_ports;
|
||||||
|
unsigned int editablePorts;
|
||||||
unsigned int points;
|
unsigned int points;
|
||||||
double minFreq, maxFreq;
|
double minFreq, maxFreq;
|
||||||
bool valid;
|
bool valid;
|
||||||
|
@ -979,6 +979,7 @@ std::vector<VirtualDevice::VNAMeasurement> Trace::assembleDatapoints(std::map<QS
|
|||||||
}
|
}
|
||||||
d.pointNum = i;
|
d.pointNum = i;
|
||||||
d.frequency = freqs[i];
|
d.frequency = freqs[i];
|
||||||
|
d.Z0 = impedance;
|
||||||
ret.push_back(d);
|
ret.push_back(d);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -7,7 +7,7 @@ ManualDeembeddingDialog::ManualDeembeddingDialog(const TraceModel &model, Deembe
|
|||||||
ui(new Ui::ManualDeembeddingDialog)
|
ui(new Ui::ManualDeembeddingDialog)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
auto traceSelector = new SparamTraceSelector(model, deemb->getAffectedPorts());
|
auto traceSelector = new SparamTraceSelector(model, deemb->getAffectedPorts(), true, 8);
|
||||||
ui->verticalLayout->insertWidget(1, traceSelector, 1.0);
|
ui->verticalLayout->insertWidget(1, traceSelector, 1.0);
|
||||||
ui->buttonBox->setEnabled(false);
|
ui->buttonBox->setEnabled(false);
|
||||||
connect(traceSelector, &SparamTraceSelector::selectionValid, ui->buttonBox, &QDialogButtonBox::setEnabled);
|
connect(traceSelector, &SparamTraceSelector::selectionValid, ui->buttonBox, &QDialogButtonBox::setEnabled);
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>508</width>
|
<width>522</width>
|
||||||
<height>168</height>
|
<height>371</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>Manual De-embedding</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -51,25 +51,33 @@ void MatchingNetwork::transformDatapoint(VirtualDevice::VNAMeasurement &p)
|
|||||||
// 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];
|
||||||
VirtualDevice::VNAMeasurement uncorrected = p;
|
VirtualDevice::VNAMeasurement uncorrected = p;
|
||||||
// correct reflection measurement (in case no two-port measurement is complete
|
// handle the measurements
|
||||||
QString name = "S"+QString::number(port)+QString::number(port);
|
for(auto &meas : p.measurements) {
|
||||||
if(uncorrected.measurements.count(name) > 0) {
|
QString name = meas.first;
|
||||||
auto S = Sparam(uncorrected.measurements[name], 0.0, 0.0, 1.0);
|
unsigned int i = name.mid(1,1).toUInt();
|
||||||
auto corrected = Sparam(m.p * ABCDparam(S, p.Z0), p.Z0);
|
unsigned int j = name.mid(2,1).toUInt();
|
||||||
p.measurements[name] = corrected.m11;
|
if(i == j) {
|
||||||
}
|
// reflection measurement
|
||||||
// handle the rest of the measurements
|
|
||||||
for(unsigned int i=1;i<=VirtualDevice::getInfo(VirtualDevice::getConnected()).ports;i++) {
|
|
||||||
for(unsigned int j=i+1;j<=VirtualDevice::getInfo(VirtualDevice::getConnected()).ports;j++) {
|
|
||||||
if(i == port) {
|
if(i == port) {
|
||||||
auto S = uncorrected.toSparam(i, j);
|
// the port of the matching network itself
|
||||||
|
auto S = Sparam(uncorrected.measurements[name], 1.0, 1.0, 0.0);
|
||||||
auto corrected = Sparam(m.p * ABCDparam(S, p.Z0), p.Z0);
|
auto corrected = Sparam(m.p * ABCDparam(S, p.Z0), p.Z0);
|
||||||
p.fromSparam(corrected, i, j);
|
p.measurements[name] = corrected.m11;
|
||||||
} else if(j == port) {
|
} else {
|
||||||
auto S = uncorrected.toSparam(i, j);
|
// another reflection measurement
|
||||||
auto corrected = Sparam(ABCDparam(S, p.Z0) * m.p, p.Z0);
|
try {
|
||||||
p.fromSparam(corrected, i, j);
|
auto S = uncorrected.toSparam(i, port);
|
||||||
|
auto corrected = Sparam(ABCDparam(S, p.Z0) * m.p, p.Z0);
|
||||||
|
p.fromSparam(corrected, i, port);
|
||||||
|
} catch (...) {
|
||||||
|
// missing measurements, nothing can be done
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// through measurement
|
||||||
|
// Already handled by reflection measurement (toSparam uses S12/S21 as well)
|
||||||
|
// and if the corresponding reflection measurement is not available, we can't
|
||||||
|
// do anything anyway
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,9 +238,11 @@ void MatchingNetwork::addComponentAtPosition(int pos, MatchingComponent *c)
|
|||||||
void MatchingNetwork::addComponent(int index, MatchingComponent *c)
|
void MatchingNetwork::addComponent(int index, MatchingComponent *c)
|
||||||
{
|
{
|
||||||
network.insert(network.begin() + index, c);
|
network.insert(network.begin() + index, c);
|
||||||
|
matching.clear();
|
||||||
// remove from list when the component deletes itself
|
// remove from list when the component deletes itself
|
||||||
connect(c, &MatchingComponent::deleted, [=](){
|
connect(c, &MatchingComponent::deleted, [=](){
|
||||||
network.erase(remove(network.begin(), network.end(), c), network.end());
|
network.erase(remove(network.begin(), network.end(), c), network.end());
|
||||||
|
matching.clear();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>913</width>
|
<width>902</width>
|
||||||
<height>633</height>
|
<height>492</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -79,7 +79,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>891</width>
|
<width>880</width>
|
||||||
<height>168</height>
|
<height>168</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
Loading…
Reference in New Issue
Block a user