Option to apply calibration and de-embedding while/after importing
This commit is contained in:
parent
f0669ab4c0
commit
7a4113cd6b
@ -5,6 +5,7 @@ HEADERS += \
|
|||||||
Calibration/calibrationtracedialog.h \
|
Calibration/calibrationtracedialog.h \
|
||||||
Calibration/calkit.h \
|
Calibration/calkit.h \
|
||||||
Calibration/calkitdialog.h \
|
Calibration/calkitdialog.h \
|
||||||
|
Calibration/manualcalibrationdialog.h \
|
||||||
Calibration/measurementmodel.h \
|
Calibration/measurementmodel.h \
|
||||||
Calibration/receivercaldialog.h \
|
Calibration/receivercaldialog.h \
|
||||||
Calibration/sourcecaldialog.h \
|
Calibration/sourcecaldialog.h \
|
||||||
@ -81,6 +82,7 @@ HEADERS += \
|
|||||||
Traces/Math/windowfunction.h \
|
Traces/Math/windowfunction.h \
|
||||||
Traces/fftcomplex.h \
|
Traces/fftcomplex.h \
|
||||||
Traces/markerwidget.h \
|
Traces/markerwidget.h \
|
||||||
|
Traces/sparamtraceselector.h \
|
||||||
Traces/trace.h \
|
Traces/trace.h \
|
||||||
Traces/tracecsvexport.h \
|
Traces/tracecsvexport.h \
|
||||||
Traces/traceeditdialog.h \
|
Traces/traceeditdialog.h \
|
||||||
@ -99,6 +101,7 @@ HEADERS += \
|
|||||||
VNA/Deembedding/deembedding.h \
|
VNA/Deembedding/deembedding.h \
|
||||||
VNA/Deembedding/deembeddingdialog.h \
|
VNA/Deembedding/deembeddingdialog.h \
|
||||||
VNA/Deembedding/deembeddingoption.h \
|
VNA/Deembedding/deembeddingoption.h \
|
||||||
|
VNA/Deembedding/manualdeembeddingdialog.h \
|
||||||
VNA/Deembedding/matchingnetwork.h \
|
VNA/Deembedding/matchingnetwork.h \
|
||||||
VNA/Deembedding/portextension.h \
|
VNA/Deembedding/portextension.h \
|
||||||
VNA/Deembedding/twothru.h \
|
VNA/Deembedding/twothru.h \
|
||||||
@ -121,6 +124,7 @@ SOURCES += \
|
|||||||
Calibration/calibrationtracedialog.cpp \
|
Calibration/calibrationtracedialog.cpp \
|
||||||
Calibration/calkit.cpp \
|
Calibration/calkit.cpp \
|
||||||
Calibration/calkitdialog.cpp \
|
Calibration/calkitdialog.cpp \
|
||||||
|
Calibration/manualcalibrationdialog.cpp \
|
||||||
Calibration/measurementmodel.cpp \
|
Calibration/measurementmodel.cpp \
|
||||||
Calibration/receivercaldialog.cpp \
|
Calibration/receivercaldialog.cpp \
|
||||||
Calibration/sourcecaldialog.cpp \
|
Calibration/sourcecaldialog.cpp \
|
||||||
@ -186,6 +190,7 @@ SOURCES += \
|
|||||||
Traces/Math/windowfunction.cpp \
|
Traces/Math/windowfunction.cpp \
|
||||||
Traces/fftcomplex.cpp \
|
Traces/fftcomplex.cpp \
|
||||||
Traces/markerwidget.cpp \
|
Traces/markerwidget.cpp \
|
||||||
|
Traces/sparamtraceselector.cpp \
|
||||||
Traces/trace.cpp \
|
Traces/trace.cpp \
|
||||||
Traces/tracecsvexport.cpp \
|
Traces/tracecsvexport.cpp \
|
||||||
Traces/traceeditdialog.cpp \
|
Traces/traceeditdialog.cpp \
|
||||||
@ -202,6 +207,7 @@ SOURCES += \
|
|||||||
VNA/Deembedding/deembedding.cpp \
|
VNA/Deembedding/deembedding.cpp \
|
||||||
VNA/Deembedding/deembeddingdialog.cpp \
|
VNA/Deembedding/deembeddingdialog.cpp \
|
||||||
VNA/Deembedding/deembeddingoption.cpp \
|
VNA/Deembedding/deembeddingoption.cpp \
|
||||||
|
VNA/Deembedding/manualdeembeddingdialog.cpp \
|
||||||
VNA/Deembedding/matchingnetwork.cpp \
|
VNA/Deembedding/matchingnetwork.cpp \
|
||||||
VNA/Deembedding/portextension.cpp \
|
VNA/Deembedding/portextension.cpp \
|
||||||
VNA/Deembedding/twothru.cpp \
|
VNA/Deembedding/twothru.cpp \
|
||||||
@ -228,6 +234,7 @@ FORMS += \
|
|||||||
Calibration/automaticamplitudedialog.ui \
|
Calibration/automaticamplitudedialog.ui \
|
||||||
Calibration/calibrationtracedialog.ui \
|
Calibration/calibrationtracedialog.ui \
|
||||||
Calibration/calkitdialog.ui \
|
Calibration/calkitdialog.ui \
|
||||||
|
Calibration/manualcalibrationdialog.ui \
|
||||||
CustomWidgets/tilewidget.ui \
|
CustomWidgets/tilewidget.ui \
|
||||||
CustomWidgets/touchstoneimport.ui \
|
CustomWidgets/touchstoneimport.ui \
|
||||||
Device/devicelog.ui \
|
Device/devicelog.ui \
|
||||||
@ -253,10 +260,12 @@ FORMS += \
|
|||||||
Traces/tracewidget.ui \
|
Traces/tracewidget.ui \
|
||||||
Traces/xyplotaxisdialog.ui \
|
Traces/xyplotaxisdialog.ui \
|
||||||
VNA/Deembedding/deembeddingdialog.ui \
|
VNA/Deembedding/deembeddingdialog.ui \
|
||||||
|
VNA/Deembedding/manualdeembeddingdialog.ui \
|
||||||
VNA/Deembedding/matchingnetworkdialog.ui \
|
VNA/Deembedding/matchingnetworkdialog.ui \
|
||||||
VNA/Deembedding/measurementdialog.ui \
|
VNA/Deembedding/measurementdialog.ui \
|
||||||
VNA/Deembedding/portextensioneditdialog.ui \
|
VNA/Deembedding/portextensioneditdialog.ui \
|
||||||
VNA/Deembedding/twothrudialog.ui \
|
VNA/Deembedding/twothrudialog.ui \
|
||||||
|
VNA/s2pImportOptions.ui \
|
||||||
main.ui \
|
main.ui \
|
||||||
preferencesdialog.ui
|
preferencesdialog.ui
|
||||||
|
|
||||||
|
@ -388,6 +388,18 @@ void Calibration::correctMeasurement(Protocol::Datapoint &d)
|
|||||||
d.imag_S22 = S22.imag();
|
d.imag_S22 = S22.imag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Calibration::correctTraces(Trace &S11, Trace &S12, Trace &S21, Trace &S22)
|
||||||
|
{
|
||||||
|
auto points = Trace::assembleDatapoints(S11, S12, S21, S22);
|
||||||
|
if(points.size()) {
|
||||||
|
// succeeded in assembling datapoints
|
||||||
|
for(auto &p : points) {
|
||||||
|
correctMeasurement(p);
|
||||||
|
}
|
||||||
|
Trace::fillFromDatapoints(S11, S12, S21, S22, points);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Calibration::InterpolationType Calibration::getInterpolation(Protocol::SweepSettings settings)
|
Calibration::InterpolationType Calibration::getInterpolation(Protocol::SweepSettings settings)
|
||||||
{
|
{
|
||||||
if(!points.size()) {
|
if(!points.size()) {
|
||||||
|
@ -47,6 +47,7 @@ public:
|
|||||||
void resetErrorTerms();
|
void resetErrorTerms();
|
||||||
|
|
||||||
void correctMeasurement(Protocol::Datapoint &d);
|
void correctMeasurement(Protocol::Datapoint &d);
|
||||||
|
void correctTraces(Trace &S11, Trace &S12, Trace &S21, Trace &S22);
|
||||||
|
|
||||||
enum class InterpolationType {
|
enum class InterpolationType {
|
||||||
Unchanged, // Nothing has changed, settings and calibration points match
|
Unchanged, // Nothing has changed, settings and calibration points match
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
#include "manualcalibrationdialog.h"
|
||||||
|
#include "ui_manualcalibrationdialog.h"
|
||||||
|
#include "Traces/sparamtraceselector.h"
|
||||||
|
|
||||||
|
ManualCalibrationDialog::ManualCalibrationDialog(const TraceModel &model, Calibration *cal) :
|
||||||
|
ui(new Ui::ManualCalibrationDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
auto traceSelector = new SparamTraceSelector(model, 2);
|
||||||
|
ui->verticalLayout->insertWidget(1, traceSelector, 1.0);
|
||||||
|
ui->buttonBox->setEnabled(false);
|
||||||
|
connect(traceSelector, &SparamTraceSelector::selectionValid, ui->buttonBox, &QDialogButtonBox::setEnabled);
|
||||||
|
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=]() {
|
||||||
|
auto t = traceSelector->getTraces();
|
||||||
|
cal->correctTraces(*t[0], *t[1], *t[2], *t[3]);
|
||||||
|
accept();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ManualCalibrationDialog::~ManualCalibrationDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef MANUALCALIBRATIONDIALOG_H
|
||||||
|
#define MANUALCALIBRATIONDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "calibration.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ManualCalibrationDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ManualCalibrationDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ManualCalibrationDialog(const TraceModel &model, Calibration *cal);
|
||||||
|
~ManualCalibrationDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::ManualCalibrationDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MANUALCALIBRATIONDIALOG_H
|
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ManualCalibrationDialog</class>
|
||||||
|
<widget class="QDialog" name="ManualCalibrationDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>597</width>
|
||||||
|
<height>200</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<property name="modal">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select the traces which contain the S parameters you want to apply the calibration to:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
172
Software/PC_Application/Traces/sparamtraceselector.cpp
Normal file
172
Software/PC_Application/Traces/sparamtraceselector.cpp
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
#include "sparamtraceselector.h"
|
||||||
|
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
SparamTraceSelector::SparamTraceSelector(const TraceModel &model, unsigned int num_ports, bool empty_allowed, std::set<unsigned int> skip)
|
||||||
|
: model(model),
|
||||||
|
num_ports(num_ports),
|
||||||
|
empty_allowed(empty_allowed)
|
||||||
|
{
|
||||||
|
// Create comboboxes
|
||||||
|
auto layout = new QFormLayout;
|
||||||
|
setLayout(layout);
|
||||||
|
for(unsigned int i=0;i<num_ports;i++) {
|
||||||
|
for(unsigned int j=0;j<num_ports;j++) {
|
||||||
|
auto label = new QLabel("S"+QString::number(i+1)+QString::number(j+1)+":");
|
||||||
|
auto box = new QComboBox();
|
||||||
|
connect(box, qOverload<int>(&QComboBox::currentIndexChanged), [=](int) {
|
||||||
|
traceSelectionChanged(box);
|
||||||
|
});
|
||||||
|
boxes.push_back(box);
|
||||||
|
layout->addRow(label, box);
|
||||||
|
if(skip.count(i*num_ports + j)) {
|
||||||
|
label->setVisible(false);
|
||||||
|
box->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setInitialChoices();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Trace*> SparamTraceSelector::getTraces()
|
||||||
|
{
|
||||||
|
vector<Trace*> ret;
|
||||||
|
for(auto b : boxes) {
|
||||||
|
if(b->currentIndex() == 0) {
|
||||||
|
ret.push_back(nullptr);
|
||||||
|
} else {
|
||||||
|
auto trace = qvariant_cast<Trace*>(b->itemData(b->currentIndex()));
|
||||||
|
ret.push_back(trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparamTraceSelector::setInitialChoices()
|
||||||
|
{
|
||||||
|
for(unsigned int i=0;i<num_ports*num_ports;i++) {
|
||||||
|
boxes[i]->blockSignals(true);
|
||||||
|
boxes[i]->clear();
|
||||||
|
boxes[i]->addItem("None");
|
||||||
|
for(auto t : model.getTraces()) {
|
||||||
|
if(t->outputType() != Trace::DataType::Frequency) {
|
||||||
|
// only frequency domain traces allowed
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(t->size() == 0) {
|
||||||
|
// can't select empty traces
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
bool reflectionRequired = i%(num_ports+1) == 0 ? true : false;
|
||||||
|
if(reflectionRequired != t->isReflection()) {
|
||||||
|
// invalid S parameter
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boxes[i]->addItem(t->name(), QVariant::fromValue<Trace*>(t));
|
||||||
|
}
|
||||||
|
boxes[i]->blockSignals(false);
|
||||||
|
}
|
||||||
|
points = 0;
|
||||||
|
valid = empty_allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparamTraceSelector::traceSelectionChanged(QComboBox *cb)
|
||||||
|
{
|
||||||
|
// update available traces in combo boxes
|
||||||
|
if(cb->currentIndex() != 0 && points == 0) {
|
||||||
|
// the first trace has been selected, extract frequency info
|
||||||
|
Trace *t = qvariant_cast<Trace*>(cb->itemData(cb->currentIndex()));
|
||||||
|
points = t->size();
|
||||||
|
if(points > 0) {
|
||||||
|
minFreq = t->minX();
|
||||||
|
maxFreq = t->maxX();
|
||||||
|
}
|
||||||
|
// remove all trace options with incompatible frequencies
|
||||||
|
for(auto c : boxes) {
|
||||||
|
if(!c->isVisible()) {
|
||||||
|
// skip invisible selections
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for(int i=1;i<c->count();i++) {
|
||||||
|
Trace *t = qvariant_cast<Trace*>(c->itemData(i));
|
||||||
|
if(t->size() != points || (points > 0 && (t->minX() != minFreq || t->maxX() != maxFreq))) {
|
||||||
|
// this trace is not available anymore
|
||||||
|
c->removeItem(i);
|
||||||
|
// decrement to check the next index in the next loop iteration
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// try to find matching traces based on their names (convenient autoselection of matching traces)
|
||||||
|
auto text = cb->currentText();
|
||||||
|
text.chop(2);
|
||||||
|
if(text.endsWith("S")) {
|
||||||
|
// tracename ended in Sxx, probably other traces with matching prefix available
|
||||||
|
for(unsigned int i=0;i<num_ports*num_ports;i++) {
|
||||||
|
auto b = boxes[i];
|
||||||
|
if(b == cb) {
|
||||||
|
// skip this box
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for(int j=0;j<b->count();j++) {
|
||||||
|
auto candidate = b->itemText(j);
|
||||||
|
// check if correct parameter
|
||||||
|
QString expectedSparam = QString::number(i/num_ports+1)+QString::number(i%num_ports+1);
|
||||||
|
if(!candidate.endsWith(expectedSparam)) {
|
||||||
|
// wrong S parameter, skip
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
candidate.chop(2);
|
||||||
|
if(candidate != text) {
|
||||||
|
// trace name does not match
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// possible match, select for this box
|
||||||
|
b->setCurrentIndex(j);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(cb->currentIndex() == 0 && points > 0) {
|
||||||
|
emit selectionValid(false);
|
||||||
|
// Check if all trace selections are set for none
|
||||||
|
for(auto c : boxes) {
|
||||||
|
if(!c->isVisible()) {
|
||||||
|
// skip invisible selections
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(c->currentIndex() != 0) {
|
||||||
|
// some trace is still selected, abort
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// all traces set for none
|
||||||
|
points = 0;
|
||||||
|
minFreq = 0;
|
||||||
|
maxFreq = 0;
|
||||||
|
setInitialChoices();
|
||||||
|
}
|
||||||
|
if(empty_allowed) {
|
||||||
|
// always valid
|
||||||
|
emit selectionValid(true);
|
||||||
|
} else {
|
||||||
|
// actually need to check
|
||||||
|
valid = true;
|
||||||
|
for(auto c : boxes) {
|
||||||
|
if(!c->isVisible()) {
|
||||||
|
// skip invisible selections
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c->currentIndex() == 0) {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit selectionValid(valid);
|
||||||
|
}
|
||||||
|
}
|
37
Software/PC_Application/Traces/sparamtraceselector.h
Normal file
37
Software/PC_Application/Traces/sparamtraceselector.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef SPARAMTRACESELECTOR_H
|
||||||
|
#define SPARAMTRACESELECTOR_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include "tracemodel.h"
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
class SparamTraceSelector : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SparamTraceSelector(const TraceModel &model, unsigned int num_ports, bool empty_allowed = false, std::set<unsigned int> skip = {});
|
||||||
|
|
||||||
|
bool isValid();
|
||||||
|
|
||||||
|
std::vector<Trace*> getTraces();
|
||||||
|
unsigned int getPoints() { return points;};
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void selectionValid(bool valid);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setInitialChoices();
|
||||||
|
void traceSelectionChanged(QComboBox *cb);
|
||||||
|
|
||||||
|
const TraceModel &model;
|
||||||
|
std::vector<QComboBox*> boxes;
|
||||||
|
unsigned int num_ports;
|
||||||
|
bool empty_allowed;
|
||||||
|
|
||||||
|
unsigned int points;
|
||||||
|
double minFreq, maxFreq;
|
||||||
|
bool valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SPARAMTRACESELECTOR_H
|
@ -2,6 +2,8 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "fftcomplex.h"
|
#include "fftcomplex.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <QSettings>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -215,6 +217,26 @@ QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
|
|||||||
return traceName;
|
return traceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Trace::fillFromDatapoints(Trace &S11, Trace &S12, Trace &S21, Trace &S22, const std::vector<Protocol::Datapoint> &data)
|
||||||
|
{
|
||||||
|
S11.clear();
|
||||||
|
S12.clear();
|
||||||
|
S21.clear();
|
||||||
|
S22.clear();
|
||||||
|
for(auto d : data) {
|
||||||
|
Trace::Data td;
|
||||||
|
td.x = d.frequency;
|
||||||
|
td.y = complex<double>(d.real_S11, d.imag_S11);
|
||||||
|
S11.addData(td);
|
||||||
|
td.y = complex<double>(d.real_S12, d.imag_S12);
|
||||||
|
S12.addData(td);
|
||||||
|
td.y = complex<double>(d.real_S21, d.imag_S21);
|
||||||
|
S21.addData(td);
|
||||||
|
td.y = complex<double>(d.real_S22, d.imag_S22);
|
||||||
|
S22.addData(td);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Trace::fromLivedata(Trace::LivedataType type, LiveParameter param)
|
void Trace::fromLivedata(Trace::LivedataType type, LiveParameter param)
|
||||||
{
|
{
|
||||||
timeDomain = false;
|
timeDomain = false;
|
||||||
@ -435,6 +457,61 @@ std::vector<Trace *> Trace::createFromCSV(CSV &csv)
|
|||||||
return traces;
|
return traces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Protocol::Datapoint> Trace::assembleDatapoints(const Trace &S11, const Trace &S12, const Trace &S21, const Trace &S22)
|
||||||
|
{
|
||||||
|
vector<Protocol::Datapoint> ret;
|
||||||
|
|
||||||
|
// Sanity check traces
|
||||||
|
unsigned int samples = S11.size();
|
||||||
|
vector<const Trace*> traces;
|
||||||
|
traces.push_back(&S11);
|
||||||
|
traces.push_back(&S12);
|
||||||
|
traces.push_back(&S21);
|
||||||
|
traces.push_back(&S22);
|
||||||
|
vector<double> freqs;
|
||||||
|
for(const auto t : traces) {
|
||||||
|
if(t->size() != samples) {
|
||||||
|
qWarning() << "Selected traces do not have the same size";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if(t->outputType() != Trace::DataType::Frequency) {
|
||||||
|
qWarning() << "Selected trace not in frequency domain";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if(freqs.empty()) {
|
||||||
|
// Create frequency vector
|
||||||
|
for(unsigned int i=0;i<samples;i++) {
|
||||||
|
freqs.push_back(t->sample(i).x);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Compare with frequency vector
|
||||||
|
for(unsigned int i=0;i<samples;i++) {
|
||||||
|
if(t->sample(i).x != freqs[i]) {
|
||||||
|
qWarning() << "Selected traces do not have identical frequency points";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks passed, assemble datapoints
|
||||||
|
for(unsigned int i=0;i<samples;i++) {
|
||||||
|
Protocol::Datapoint d;
|
||||||
|
d.real_S11 = real(S11.sample(i).y);
|
||||||
|
d.imag_S11 = imag(S11.sample(i).y);
|
||||||
|
d.real_S12 = real(S12.sample(i).y);
|
||||||
|
d.imag_S12 = imag(S12.sample(i).y);
|
||||||
|
d.real_S21 = real(S21.sample(i).y);
|
||||||
|
d.imag_S21 = imag(S21.sample(i).y);
|
||||||
|
d.real_S22 = real(S22.sample(i).y);
|
||||||
|
d.imag_S22 = imag(S22.sample(i).y);
|
||||||
|
d.pointNum = i;
|
||||||
|
d.frequency = freqs[i];
|
||||||
|
ret.push_back(d);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void Trace::updateLastMath(vector<MathInfo>::reverse_iterator start)
|
void Trace::updateLastMath(vector<MathInfo>::reverse_iterator start)
|
||||||
{
|
{
|
||||||
TraceMath *newLast = nullptr;
|
TraceMath *newLast = nullptr;
|
||||||
@ -626,7 +703,7 @@ void Trace::enableMathOperation(unsigned int index, bool enable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Trace::size()
|
unsigned int Trace::size() const
|
||||||
{
|
{
|
||||||
return lastMath->numSamples();
|
return lastMath->numSamples();
|
||||||
}
|
}
|
||||||
@ -724,7 +801,7 @@ std::vector<double> Trace::findPeakFrequencies(unsigned int maxPeaks, double min
|
|||||||
return frequencies;
|
return frequencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
Trace::Data Trace::sample(unsigned int index, SampleType type)
|
Trace::Data Trace::sample(unsigned int index, SampleType type) const
|
||||||
{
|
{
|
||||||
auto data = lastMath->getSample(index);
|
auto data = lastMath->getSample(index);
|
||||||
if(type == SampleType::TimeStep) {
|
if(type == SampleType::TimeStep) {
|
||||||
|
@ -47,6 +47,7 @@ public:
|
|||||||
void setVelocityFactor(double v);
|
void setVelocityFactor(double v);
|
||||||
void fillFromTouchstone(Touchstone &t, unsigned int parameter);
|
void fillFromTouchstone(Touchstone &t, unsigned int parameter);
|
||||||
QString fillFromCSV(CSV &csv, unsigned int parameter); // returns the suggested trace name (not yet set in member data)
|
QString fillFromCSV(CSV &csv, unsigned int parameter); // returns the suggested trace name (not yet set in member data)
|
||||||
|
static void fillFromDatapoints(Trace &S11, Trace &S12, Trace &S21, Trace &S22, const std::vector<Protocol::Datapoint> &data);
|
||||||
void fromLivedata(LivedataType type, LiveParameter param);
|
void fromLivedata(LivedataType type, LiveParameter param);
|
||||||
QString name() { return _name; };
|
QString name() { return _name; };
|
||||||
QColor color() { return _color; };
|
QColor color() { return _color; };
|
||||||
@ -60,8 +61,8 @@ public:
|
|||||||
bool isReflection();
|
bool isReflection();
|
||||||
LiveParameter liveParameter() { return _liveParam; }
|
LiveParameter liveParameter() { return _liveParam; }
|
||||||
LivedataType liveType() { return _liveType; }
|
LivedataType liveType() { return _liveType; }
|
||||||
TraceMath::DataType outputType() { return lastMath->getDataType(); };
|
TraceMath::DataType outputType() const { return lastMath->getDataType(); };
|
||||||
unsigned int size();
|
unsigned int size() const;
|
||||||
double minX();
|
double minX();
|
||||||
double maxX();
|
double maxX();
|
||||||
double findExtremumFreq(bool max);
|
double findExtremumFreq(bool max);
|
||||||
@ -77,7 +78,7 @@ public:
|
|||||||
TimeStep,
|
TimeStep,
|
||||||
};
|
};
|
||||||
|
|
||||||
Data sample(unsigned int index, SampleType type = SampleType::Frequency);
|
Data sample(unsigned int index, SampleType type = SampleType::Frequency) const;
|
||||||
QString getFilename() const;
|
QString getFilename() const;
|
||||||
unsigned int getFileParameter() const;
|
unsigned int getFileParameter() const;
|
||||||
/* Returns the noise in dbm/Hz for spectrum analyzer measurements. May return NaN if calculation not possible */
|
/* Returns the noise in dbm/Hz for spectrum analyzer measurements. May return NaN if calculation not possible */
|
||||||
@ -125,6 +126,10 @@ public:
|
|||||||
static std::vector<Trace*> createFromTouchstone(Touchstone &t);
|
static std::vector<Trace*> createFromTouchstone(Touchstone &t);
|
||||||
static std::vector<Trace*> createFromCSV(CSV &csv);
|
static std::vector<Trace*> createFromCSV(CSV &csv);
|
||||||
|
|
||||||
|
// Assembles datapoints as received from the VNA from four S parameter traces. Requires that all traces are in the frequency domain,
|
||||||
|
// have the same number of samples and their samples must be at the same frequencies across all traces
|
||||||
|
static std::vector<Protocol::Datapoint> assembleDatapoints(const Trace &S11, const Trace &S12, const Trace &S21, const Trace &S22);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setVisible(bool visible);
|
void setVisible(bool visible);
|
||||||
void setColor(QColor color);
|
void setColor(QColor color);
|
||||||
|
@ -143,7 +143,7 @@ QVariant TraceModel::data(const QModelIndex &index, int role) const
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Trace *> TraceModel::getTraces()
|
std::vector<Trace *> TraceModel::getTraces() const
|
||||||
{
|
{
|
||||||
return traces;
|
return traces;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
QVariant data(const QModelIndex &index, int role) const override;
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
|
||||||
std::vector<Trace*> getTraces();
|
std::vector<Trace*> getTraces() const;
|
||||||
|
|
||||||
bool PortExcitationRequired(int port);
|
bool PortExcitationRequired(int port);
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "deembeddingdialog.h"
|
#include "deembeddingdialog.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include "ui_measurementdialog.h"
|
#include "ui_measurementdialog.h"
|
||||||
|
#include "Traces/sparamtraceselector.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -24,170 +25,49 @@ void Deembedding::measurementCompleted()
|
|||||||
measurementUI = nullptr;
|
measurementUI = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Deembedding::setInitialTraceSelections()
|
|
||||||
{
|
|
||||||
// all checkboxes initially set to none
|
|
||||||
measurementUI->cS11->blockSignals(true);
|
|
||||||
measurementUI->cS12->blockSignals(true);
|
|
||||||
measurementUI->cS21->blockSignals(true);
|
|
||||||
measurementUI->cS22->blockSignals(true);
|
|
||||||
measurementUI->cS11->clear();
|
|
||||||
measurementUI->cS12->clear();
|
|
||||||
measurementUI->cS21->clear();
|
|
||||||
measurementUI->cS22->clear();
|
|
||||||
measurementUI->cS11->addItem("None");
|
|
||||||
measurementUI->cS12->addItem("None");
|
|
||||||
measurementUI->cS21->addItem("None");
|
|
||||||
measurementUI->cS22->addItem("None");
|
|
||||||
// add applicable traces
|
|
||||||
for(auto t : tm.getTraces()) {
|
|
||||||
if(t->isReflection()) {
|
|
||||||
measurementUI->cS11->addItem(t->name(), QVariant::fromValue<Trace*>(t));
|
|
||||||
measurementUI->cS22->addItem(t->name(), QVariant::fromValue<Trace*>(t));
|
|
||||||
} else {
|
|
||||||
measurementUI->cS12->addItem(t->name(), QVariant::fromValue<Trace*>(t));
|
|
||||||
measurementUI->cS21->addItem(t->name(), QVariant::fromValue<Trace*>(t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
measurementUI->cS11->blockSignals(false);
|
|
||||||
measurementUI->cS12->blockSignals(false);
|
|
||||||
measurementUI->cS21->blockSignals(false);
|
|
||||||
measurementUI->cS22->blockSignals(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Deembedding::traceSelectionChanged(QComboBox *w)
|
|
||||||
{
|
|
||||||
vector<QComboBox*> cbs;
|
|
||||||
if (measurementUI->cS11->isVisible()) {
|
|
||||||
cbs.push_back(measurementUI->cS11);
|
|
||||||
}
|
|
||||||
if (measurementUI->cS12->isVisible()) {
|
|
||||||
cbs.push_back(measurementUI->cS12);
|
|
||||||
}
|
|
||||||
if (measurementUI->cS21->isVisible()) {
|
|
||||||
cbs.push_back(measurementUI->cS21);
|
|
||||||
}
|
|
||||||
if (measurementUI->cS22->isVisible()) {
|
|
||||||
cbs.push_back(measurementUI->cS22);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update available traces in combo boxes
|
|
||||||
if(w->currentIndex() != 0 && points == 0) {
|
|
||||||
// the first trace has been selected, extract frequency info
|
|
||||||
Trace *t = qvariant_cast<Trace*>(w->itemData(w->currentIndex()));
|
|
||||||
points = t->size();
|
|
||||||
if(points > 0) {
|
|
||||||
minFreq = t->minX();
|
|
||||||
maxFreq = t->maxX();
|
|
||||||
}
|
|
||||||
// remove all trace options with incompatible frequencies
|
|
||||||
for(auto c : cbs) {
|
|
||||||
for(int i=1;i<c->count();i++) {
|
|
||||||
Trace *t = qvariant_cast<Trace*>(c->itemData(i));
|
|
||||||
if(t->size() != points || (points > 0 && (t->minX() != minFreq || t->maxX() != maxFreq))) {
|
|
||||||
// this trace is not available anymore
|
|
||||||
c->removeItem(i);
|
|
||||||
// decrement to check the next index in the next loop iteration
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if(w->currentIndex() == 0 && points > 0) {
|
|
||||||
measurementUI->buttonBox->setEnabled(false);
|
|
||||||
// Check if all trace selections are set for none
|
|
||||||
for(auto c : cbs) {
|
|
||||||
if(c->currentIndex() != 0) {
|
|
||||||
// some trace is still selected, abort
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// all traces set for none
|
|
||||||
points = 0;
|
|
||||||
minFreq = 0;
|
|
||||||
maxFreq = 0;
|
|
||||||
setInitialTraceSelections();
|
|
||||||
}
|
|
||||||
bool allSelectionsValid = true;
|
|
||||||
for(auto c : cbs) {
|
|
||||||
if (c->currentIndex() == 0) {
|
|
||||||
allSelectionsValid = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(allSelectionsValid) {
|
|
||||||
measurementUI->buttonBox->setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Deembedding::startMeasurementDialog(bool S11, bool S12, bool S21, bool S22)
|
void Deembedding::startMeasurementDialog(bool S11, bool S12, bool S21, bool S22)
|
||||||
{
|
{
|
||||||
measurements.clear();
|
measurements.clear();
|
||||||
|
|
||||||
points = 0;
|
|
||||||
minFreq = 0.0;
|
|
||||||
maxFreq = 0.0;
|
|
||||||
|
|
||||||
measurementDialog = new QDialog;
|
measurementDialog = new QDialog;
|
||||||
auto ui = new Ui_DeembeddingMeasurementDialog;
|
auto ui = new Ui_DeembeddingMeasurementDialog;
|
||||||
measurementUI = ui;
|
measurementUI = ui;
|
||||||
ui->setupUi(measurementDialog);
|
ui->setupUi(measurementDialog);
|
||||||
// disable not needed GUI elements
|
|
||||||
|
// add the trace selector
|
||||||
|
set<unsigned int> skip;
|
||||||
if(!S11) {
|
if(!S11) {
|
||||||
ui->lS11->setVisible(false);
|
skip.insert(0);
|
||||||
ui->cS11->setVisible(false);
|
|
||||||
}
|
}
|
||||||
if(!S12) {
|
if(!S12) {
|
||||||
ui->lS12->setVisible(false);
|
skip.insert(1);
|
||||||
ui->cS12->setVisible(false);
|
|
||||||
}
|
}
|
||||||
if(!S21) {
|
if(!S21) {
|
||||||
ui->lS21->setVisible(false);
|
skip.insert(2);
|
||||||
ui->cS21->setVisible(false);
|
|
||||||
}
|
}
|
||||||
if(!S22) {
|
if(!S22) {
|
||||||
ui->lS22->setVisible(false);
|
skip.insert(3);
|
||||||
ui->cS22->setVisible(false);
|
|
||||||
}
|
}
|
||||||
|
auto traceChooser = new SparamTraceSelector(tm, 2, false, skip);
|
||||||
|
ui->horizontalLayout_2->insertWidget(0, traceChooser, 1);
|
||||||
|
|
||||||
|
connect(traceChooser, &SparamTraceSelector::selectionValid, ui->buttonBox, &QDialogButtonBox::setEnabled);
|
||||||
|
|
||||||
connect(ui->bMeasure, &QPushButton::clicked, [=](){
|
connect(ui->bMeasure, &QPushButton::clicked, [=](){
|
||||||
ui->bMeasure->setEnabled(false);
|
ui->bMeasure->setEnabled(false);
|
||||||
ui->cS11->setEnabled(false);
|
traceChooser->setEnabled(false);
|
||||||
ui->cS12->setEnabled(false);
|
|
||||||
ui->cS21->setEnabled(false);
|
|
||||||
ui->cS22->setEnabled(false);
|
|
||||||
ui->buttonBox->setEnabled(false);
|
ui->buttonBox->setEnabled(false);
|
||||||
measuring = true;
|
measuring = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->cS11, qOverload<int>(&QComboBox::currentIndexChanged), [=](int){
|
|
||||||
traceSelectionChanged(ui->cS11);
|
|
||||||
});
|
|
||||||
connect(ui->cS12, qOverload<int>(&QComboBox::currentIndexChanged), [=](int){
|
|
||||||
traceSelectionChanged(ui->cS12);
|
|
||||||
});
|
|
||||||
connect(ui->cS21, qOverload<int>(&QComboBox::currentIndexChanged), [=](int){
|
|
||||||
traceSelectionChanged(ui->cS21);
|
|
||||||
});
|
|
||||||
connect(ui->cS22, qOverload<int>(&QComboBox::currentIndexChanged), [=](int){
|
|
||||||
traceSelectionChanged(ui->cS22);
|
|
||||||
});
|
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){
|
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){
|
||||||
// create datapoints from individual traces
|
// create datapoints from individual traces
|
||||||
measurements.clear();
|
measurements.clear();
|
||||||
Trace *S11 = nullptr, *S12 = nullptr, *S21 = nullptr, *S22 = nullptr;
|
auto t = traceChooser->getTraces();
|
||||||
if (ui->cS11->currentIndex() != 0) {
|
auto S11 = t[0];
|
||||||
S11 = qvariant_cast<Trace*>(ui->cS11->itemData(ui->cS11->currentIndex()));
|
auto S12 = t[1];
|
||||||
}
|
auto S21 = t[2];
|
||||||
if (ui->cS12->currentIndex() != 0) {
|
auto S22 = t[3];
|
||||||
S12 = qvariant_cast<Trace*>(ui->cS12->itemData(ui->cS12->currentIndex()));
|
for(unsigned int i=0;i<traceChooser->getPoints();i++) {
|
||||||
}
|
|
||||||
if (ui->cS21->currentIndex() != 0) {
|
|
||||||
S21 = qvariant_cast<Trace*>(ui->cS21->itemData(ui->cS21->currentIndex()));
|
|
||||||
}
|
|
||||||
if (ui->cS22->currentIndex() != 0) {
|
|
||||||
S22 = qvariant_cast<Trace*>(ui->cS22->itemData(ui->cS22->currentIndex()));
|
|
||||||
}
|
|
||||||
for(unsigned int i=0;i<points;i++) {
|
|
||||||
Protocol::Datapoint p;
|
Protocol::Datapoint p;
|
||||||
p.pointNum = i;
|
p.pointNum = i;
|
||||||
if(S11) {
|
if(S11) {
|
||||||
@ -219,15 +99,12 @@ void Deembedding::startMeasurementDialog(bool S11, bool S12, bool S21, bool S22)
|
|||||||
measurementCompleted();
|
measurementCompleted();
|
||||||
});
|
});
|
||||||
|
|
||||||
setInitialTraceSelections();
|
|
||||||
|
|
||||||
measurementDialog->show();
|
measurementDialog->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
Deembedding::Deembedding(TraceModel &tm)
|
Deembedding::Deembedding(TraceModel &tm)
|
||||||
: tm(tm),
|
: tm(tm),
|
||||||
measuring(false),
|
measuring(false)
|
||||||
points(0)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -268,12 +145,27 @@ void Deembedding::Deembed(Protocol::Datapoint &d)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Deembedding::Deembed(Trace &S11, Trace &S12, Trace &S21, Trace &S22)
|
||||||
|
{
|
||||||
|
auto points = Trace::assembleDatapoints(S11, S12, S21, S22);
|
||||||
|
if(points.size()) {
|
||||||
|
// succeeded in assembling datapoints
|
||||||
|
for(auto &p : points) {
|
||||||
|
Deembed(p);
|
||||||
|
}
|
||||||
|
Trace::fillFromDatapoints(S11, S12, S21, S22, points);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Deembedding::removeOption(unsigned int index)
|
void Deembedding::removeOption(unsigned int index)
|
||||||
{
|
{
|
||||||
if(index < options.size()) {
|
if(index < options.size()) {
|
||||||
delete options[index];
|
delete options[index];
|
||||||
options.erase(options.begin() + index);
|
options.erase(options.begin() + index);
|
||||||
}
|
}
|
||||||
|
if(options.size() == 0) {
|
||||||
|
emit allOptionsCleared();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Deembedding::addOption(DeembeddingOption *option)
|
void Deembedding::addOption(DeembeddingOption *option)
|
||||||
@ -290,6 +182,7 @@ void Deembedding::addOption(DeembeddingOption *option)
|
|||||||
measuringOption = option;
|
measuringOption = option;
|
||||||
startMeasurementDialog(S11, S12, S21, S22);
|
startMeasurementDialog(S11, S12, S21, S22);
|
||||||
});
|
});
|
||||||
|
emit optionAdded();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Deembedding::swapOptions(unsigned int index)
|
void Deembedding::swapOptions(unsigned int index)
|
||||||
|
@ -19,6 +19,7 @@ public:
|
|||||||
~Deembedding(){};
|
~Deembedding(){};
|
||||||
|
|
||||||
void Deembed(Protocol::Datapoint &d);
|
void Deembed(Protocol::Datapoint &d);
|
||||||
|
void Deembed(Trace &S11, Trace &S12, Trace &S21, Trace &S22);
|
||||||
|
|
||||||
void removeOption(unsigned int index);
|
void removeOption(unsigned int index);
|
||||||
void addOption(DeembeddingOption* option);
|
void addOption(DeembeddingOption* option);
|
||||||
@ -30,10 +31,10 @@ public slots:
|
|||||||
void configure();
|
void configure();
|
||||||
signals:
|
signals:
|
||||||
void triggerMeasurement(bool S11 = true, bool S12 = true, bool S21 = true, bool S22 = true);
|
void triggerMeasurement(bool S11 = true, bool S12 = true, bool S21 = true, bool S22 = true);
|
||||||
|
void optionAdded();
|
||||||
|
void allOptionsCleared();
|
||||||
private:
|
private:
|
||||||
void measurementCompleted();
|
void measurementCompleted();
|
||||||
void setInitialTraceSelections();
|
|
||||||
void traceSelectionChanged(QComboBox *w);
|
|
||||||
void startMeasurementDialog(bool S11, bool S12, bool S21, bool S22);
|
void startMeasurementDialog(bool S11, bool S12, bool S21, bool S22);
|
||||||
std::vector<DeembeddingOption*> options;
|
std::vector<DeembeddingOption*> options;
|
||||||
DeembeddingOption *measuringOption;
|
DeembeddingOption *measuringOption;
|
||||||
@ -43,9 +44,6 @@ private:
|
|||||||
std::vector<Protocol::Datapoint> measurements;
|
std::vector<Protocol::Datapoint> measurements;
|
||||||
QDialog *measurementDialog;
|
QDialog *measurementDialog;
|
||||||
Ui_DeembeddingMeasurementDialog *measurementUI;
|
Ui_DeembeddingMeasurementDialog *measurementUI;
|
||||||
// parameters of the selected traces for the measurement
|
|
||||||
double minFreq, maxFreq;
|
|
||||||
unsigned long points;
|
|
||||||
|
|
||||||
unsigned long sweepPoints;
|
unsigned long sweepPoints;
|
||||||
|
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
#include "manualdeembeddingdialog.h"
|
||||||
|
#include "ui_manualdeembeddingdialog.h"
|
||||||
|
#include "Traces/sparamtraceselector.h"
|
||||||
|
|
||||||
|
ManualDeembeddingDialog::ManualDeembeddingDialog(const TraceModel &model, Deembedding *deemb) :
|
||||||
|
ui(new Ui::ManualDeembeddingDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
auto traceSelector = new SparamTraceSelector(model, 2);
|
||||||
|
ui->verticalLayout->insertWidget(1, traceSelector, 1.0);
|
||||||
|
ui->buttonBox->setEnabled(false);
|
||||||
|
connect(traceSelector, &SparamTraceSelector::selectionValid, ui->buttonBox, &QDialogButtonBox::setEnabled);
|
||||||
|
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=]() {
|
||||||
|
auto t = traceSelector->getTraces();
|
||||||
|
deemb->Deembed(*t[0], *t[1], *t[2], *t[3]);
|
||||||
|
accept();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ManualDeembeddingDialog::~ManualDeembeddingDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef MANUALDEEMBEDDINGDIALOG_H
|
||||||
|
#define MANUALDEEMBEDDINGDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "Traces/tracemodel.h"
|
||||||
|
#include "deembedding.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ManualDeembeddingDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ManualDeembeddingDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ManualDeembeddingDialog(const TraceModel &model, Deembedding *deemb);
|
||||||
|
~ManualDeembeddingDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::ManualDeembeddingDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MANUALDEEMBEDDINGDIALOG_H
|
@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ManualDeembeddingDialog</class>
|
||||||
|
<widget class="QDialog" name="ManualDeembeddingDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>508</width>
|
||||||
|
<height>168</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<property name="modal">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select the traces which contain the S parameters you want to de-embed:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>ManualDeembeddingDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>ManualDeembeddingDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
@ -60,51 +60,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0">
|
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0">
|
||||||
<item>
|
|
||||||
<layout class="QFormLayout" name="formLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="lS11">
|
|
||||||
<property name="text">
|
|
||||||
<string>S11:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QComboBox" name="cS11"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="lS12">
|
|
||||||
<property name="text">
|
|
||||||
<string>S12:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QComboBox" name="cS12"/>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="lS21">
|
|
||||||
<property name="text">
|
|
||||||
<string>S21:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QComboBox" name="cS21"/>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="lS22">
|
|
||||||
<property name="text">
|
|
||||||
<string>S22:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QComboBox" name="cS22"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
|
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
|
||||||
<item>
|
<item>
|
||||||
|
91
Software/PC_Application/VNA/s2pImportOptions.ui
Normal file
91
Software/PC_Application/VNA/s2pImportOptions.ui
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>s2pImportOptions</class>
|
||||||
|
<widget class="QDialog" name="s2pImportOptions">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>285</width>
|
||||||
|
<height>178</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Import Options</string>
|
||||||
|
</property>
|
||||||
|
<property name="modal">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>You imported a two-port touchstone file, do you want to apply the currently active calibration or de-embed the data?</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="applyCal">
|
||||||
|
<property name="text">
|
||||||
|
<string>Apply Calibration</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="deembed">
|
||||||
|
<property name="text">
|
||||||
|
<string>De-embed imported traces</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>s2pImportOptions</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>s2pImportOptions</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
@ -5,11 +5,14 @@
|
|||||||
#include "Traces/tracetouchstoneexport.h"
|
#include "Traces/tracetouchstoneexport.h"
|
||||||
#include "Traces/tracecsvexport.h"
|
#include "Traces/tracecsvexport.h"
|
||||||
#include "ui_tracewidget.h"
|
#include "ui_tracewidget.h"
|
||||||
|
#include "ui_s2pImportOptions.h"
|
||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
|
||||||
TraceWidgetVNA::TraceWidgetVNA(TraceModel &model, QWidget *parent)
|
TraceWidgetVNA::TraceWidgetVNA(TraceModel &model, Calibration &cal, Deembedding &deembed, QWidget *parent)
|
||||||
: TraceWidget(model, parent)
|
: TraceWidget(model, parent),
|
||||||
|
cal(cal),
|
||||||
|
deembed(deembed)
|
||||||
{
|
{
|
||||||
auto exportMenu = new QMenu();
|
auto exportMenu = new QMenu();
|
||||||
auto exportTouchstone = new QAction("Touchstone");
|
auto exportTouchstone = new QAction("Touchstone");
|
||||||
@ -68,9 +71,34 @@ void TraceWidgetVNA::importDialog()
|
|||||||
i->show();
|
i->show();
|
||||||
if(filename.endsWith(".s2p")) {
|
if(filename.endsWith(".s2p")) {
|
||||||
// potential candidate to process via calibration/de-embedding
|
// potential candidate to process via calibration/de-embedding
|
||||||
connect(i, &TraceImportDialog::importFinsished, [](const std::vector<Trace*> &traces) {
|
connect(i, &TraceImportDialog::importFinsished, [=](const std::vector<Trace*> &traces) {
|
||||||
if(traces.size() == 4) {
|
if(traces.size() == 4) {
|
||||||
// all traces imported, can calculate calibration/de-embedding
|
// all traces imported, can calculate calibration/de-embedding
|
||||||
|
bool calAvailable = cal.nPoints() > 0;
|
||||||
|
bool deembedAvailable = deembed.getOptions().size() > 0;
|
||||||
|
if(calAvailable || deembedAvailable) {
|
||||||
|
// check if user wants to apply either one to the imported traces
|
||||||
|
auto dialog = new QDialog();
|
||||||
|
auto ui = new Ui::s2pImportOptions;
|
||||||
|
ui->setupUi(dialog);
|
||||||
|
ui->applyCal->setEnabled(calAvailable);
|
||||||
|
ui->deembed->setEnabled(deembedAvailable);
|
||||||
|
bool applyCal = false;
|
||||||
|
bool applyDeembed = false;
|
||||||
|
connect(ui->applyCal, &QCheckBox::toggled, [&](bool checked) {
|
||||||
|
applyCal = checked;
|
||||||
|
});
|
||||||
|
connect(ui->deembed, &QCheckBox::toggled, [&](bool checked) {
|
||||||
|
applyDeembed = checked;
|
||||||
|
});
|
||||||
|
dialog->exec();
|
||||||
|
if(applyCal) {
|
||||||
|
cal.correctTraces(*traces[0], *traces[1], *traces[2], *traces[3]);
|
||||||
|
}
|
||||||
|
if(applyDeembed) {
|
||||||
|
deembed.Deembed(*traces[0], *traces[1], *traces[2], *traces[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2,17 +2,22 @@
|
|||||||
#define TRACEWIDGETVNA_H
|
#define TRACEWIDGETVNA_H
|
||||||
|
|
||||||
#include "Traces/tracewidget.h"
|
#include "Traces/tracewidget.h"
|
||||||
|
#include "Calibration/calibration.h"
|
||||||
|
#include "Deembedding/deembedding.h"
|
||||||
|
|
||||||
class TraceWidgetVNA : public TraceWidget
|
class TraceWidgetVNA : public TraceWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TraceWidgetVNA(TraceModel &model, QWidget *parent = nullptr);
|
TraceWidgetVNA(TraceModel &model, Calibration &cal, Deembedding &deembed, QWidget *parent = nullptr);
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void exportDialog() override {};
|
virtual void exportDialog() override {};
|
||||||
virtual void importDialog() override;
|
virtual void importDialog() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Trace::LiveParameter defaultParameter() override {return Trace::LiveParameter::S11;};
|
virtual Trace::LiveParameter defaultParameter() override {return Trace::LiveParameter::S11;};
|
||||||
|
// These can optionally be applied when importing an s2p file
|
||||||
|
Calibration &cal;
|
||||||
|
Deembedding &deembed;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRACEWIDGETVNA_H
|
#endif // TRACEWIDGETVNA_H
|
||||||
|
@ -44,6 +44,8 @@
|
|||||||
#include <QErrorMessage>
|
#include <QErrorMessage>
|
||||||
#include "CustomWidgets/informationbox.h"
|
#include "CustomWidgets/informationbox.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include "Deembedding/manualdeembeddingdialog.h"
|
||||||
|
#include "Calibration/manualcalibrationdialog.h"
|
||||||
|
|
||||||
VNA::VNA(AppWindow *window)
|
VNA::VNA(AppWindow *window)
|
||||||
: Mode(window, "Vector Network Analyzer"),
|
: Mode(window, "Vector Network Analyzer"),
|
||||||
@ -148,16 +150,51 @@ VNA::VNA(AppWindow *window)
|
|||||||
import->show();
|
import->show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
calMenu->addSeparator();
|
||||||
|
auto calApplyToTraces = calMenu->addAction("Apply to traces...");
|
||||||
|
calApplyToTraces->setEnabled(false);
|
||||||
|
connect(calApplyToTraces, &QAction::triggered, [=]() {
|
||||||
|
auto manualCalibration = new ManualCalibrationDialog(traceModel, &cal);
|
||||||
|
manualCalibration->show();
|
||||||
|
});
|
||||||
|
|
||||||
// portExtension.setCalkit(&cal.getCalibrationKit());
|
// portExtension.setCalkit(&cal.getCalibrationKit());
|
||||||
|
|
||||||
|
// De-embedding menu
|
||||||
|
auto menuDeembed = new QMenu("De-embedding", window);
|
||||||
|
window->menuBar()->insertMenu(window->getUi()->menuWindow->menuAction(), menuDeembed);
|
||||||
|
auto confDeembed = menuDeembed->addAction("Setup...");
|
||||||
|
connect(confDeembed, &QAction::triggered, &deembedding, &Deembedding::configure);
|
||||||
|
|
||||||
|
enableDeembeddingAction = menuDeembed->addAction("De-embed VNA samples");
|
||||||
|
enableDeembeddingAction->setCheckable(true);
|
||||||
|
enableDeembeddingAction->setEnabled(false);
|
||||||
|
connect(enableDeembeddingAction, &QAction::toggled, this, &VNA::EnableDeembedding);
|
||||||
|
|
||||||
|
auto manualDeembed = menuDeembed->addAction("De-embed traces...");
|
||||||
|
manualDeembed->setEnabled(false);
|
||||||
|
connect(manualDeembed, &QAction::triggered, [=]() {
|
||||||
|
auto manualDeembedding = new ManualDeembeddingDialog(traceModel, &deembedding);
|
||||||
|
manualDeembedding->show();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(&deembedding, &Deembedding::optionAdded, [=](){
|
||||||
|
EnableDeembedding(true);
|
||||||
|
enableDeembeddingAction->setEnabled(true);
|
||||||
|
manualDeembed->setEnabled(true);
|
||||||
|
});
|
||||||
|
connect(&deembedding, &Deembedding::allOptionsCleared, [=](){
|
||||||
|
EnableDeembedding(false);
|
||||||
|
enableDeembeddingAction->setEnabled(false);
|
||||||
|
manualDeembed->setEnabled(false);
|
||||||
|
});
|
||||||
|
|
||||||
// Tools menu
|
// Tools menu
|
||||||
auto toolsMenu = new QMenu("Tools", window);
|
auto toolsMenu = new QMenu("Tools", window);
|
||||||
window->menuBar()->insertMenu(window->getUi()->menuWindow->menuAction(), toolsMenu);
|
window->menuBar()->insertMenu(window->getUi()->menuWindow->menuAction(), toolsMenu);
|
||||||
actions.insert(toolsMenu->menuAction());
|
actions.insert(toolsMenu->menuAction());
|
||||||
auto impedanceMatching = toolsMenu->addAction("Impedance Matching");
|
auto impedanceMatching = toolsMenu->addAction("Impedance Matching");
|
||||||
connect(impedanceMatching, &QAction::triggered, this, &VNA::StartImpedanceMatching);
|
connect(impedanceMatching, &QAction::triggered, this, &VNA::StartImpedanceMatching);
|
||||||
auto confDeembed = toolsMenu->addAction("De-embedding");
|
|
||||||
connect(confDeembed, &QAction::triggered, &deembedding, &Deembedding::configure);
|
|
||||||
|
|
||||||
defaultCalMenu = new QMenu("Default Calibration", window);
|
defaultCalMenu = new QMenu("Default Calibration", window);
|
||||||
assignDefaultCal = defaultCalMenu->addAction("Assign...");
|
assignDefaultCal = defaultCalMenu->addAction("Assign...");
|
||||||
@ -342,6 +379,7 @@ VNA::VNA(AppWindow *window)
|
|||||||
cbEnableCal->blockSignals(false);
|
cbEnableCal->blockSignals(false);
|
||||||
calImportTerms->setEnabled(false);
|
calImportTerms->setEnabled(false);
|
||||||
calImportMeas->setEnabled(false);
|
calImportMeas->setEnabled(false);
|
||||||
|
calApplyToTraces->setEnabled(false);
|
||||||
saveCal->setEnabled(false);
|
saveCal->setEnabled(false);
|
||||||
});
|
});
|
||||||
connect(calDisable, &QAction::triggered, this, &VNA::DisableCalibration);
|
connect(calDisable, &QAction::triggered, this, &VNA::DisableCalibration);
|
||||||
@ -362,6 +400,7 @@ VNA::VNA(AppWindow *window)
|
|||||||
cbEnableCal->blockSignals(false);
|
cbEnableCal->blockSignals(false);
|
||||||
calImportTerms->setEnabled(true);
|
calImportTerms->setEnabled(true);
|
||||||
calImportMeas->setEnabled(true);
|
calImportMeas->setEnabled(true);
|
||||||
|
calApplyToTraces->setEnabled(true);
|
||||||
saveCal->setEnabled(true);
|
saveCal->setEnabled(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -378,7 +417,7 @@ VNA::VNA(AppWindow *window)
|
|||||||
markerModel = new TraceMarkerModel(traceModel, this);
|
markerModel = new TraceMarkerModel(traceModel, this);
|
||||||
|
|
||||||
auto tracesDock = new QDockWidget("Traces");
|
auto tracesDock = new QDockWidget("Traces");
|
||||||
tracesDock->setWidget(new TraceWidgetVNA(traceModel));
|
tracesDock->setWidget(new TraceWidgetVNA(traceModel, cal, deembedding));
|
||||||
window->addDockWidget(Qt::LeftDockWidgetArea, tracesDock);
|
window->addDockWidget(Qt::LeftDockWidgetArea, tracesDock);
|
||||||
docks.insert(tracesDock);
|
docks.insert(tracesDock);
|
||||||
|
|
||||||
@ -532,6 +571,7 @@ nlohmann::json VNA::toJSON()
|
|||||||
j["tiles"] = central->toJSON();
|
j["tiles"] = central->toJSON();
|
||||||
j["markers"] = markerModel->toJSON();
|
j["markers"] = markerModel->toJSON();
|
||||||
j["de-embedding"] = deembedding.toJSON();
|
j["de-embedding"] = deembedding.toJSON();
|
||||||
|
j["de-embedding_enabled"] = deembedding_active;
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,6 +588,9 @@ void VNA::fromJSON(nlohmann::json j)
|
|||||||
}
|
}
|
||||||
if(j.contains("de-embedding")) {
|
if(j.contains("de-embedding")) {
|
||||||
deembedding.fromJSON(j["de-embedding"]);
|
deembedding.fromJSON(j["de-embedding"]);
|
||||||
|
EnableDeembedding(j.value("de-embedding_enabled", true));
|
||||||
|
} else {
|
||||||
|
EnableDeembedding(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,7 +619,9 @@ void VNA::NewDatapoint(Protocol::Datapoint d)
|
|||||||
cal.correctMeasurement(d);
|
cal.correctMeasurement(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
deembedding.Deembed(d);
|
if(deembedding_active) {
|
||||||
|
deembedding.Deembed(d);
|
||||||
|
}
|
||||||
|
|
||||||
traceModel.addVNAData(d, settings);
|
traceModel.addVNAData(d, settings);
|
||||||
emit dataChanged();
|
emit dataChanged();
|
||||||
@ -766,6 +811,7 @@ void VNA::DisableCalibration(bool force)
|
|||||||
{
|
{
|
||||||
if(calValid || force) {
|
if(calValid || force) {
|
||||||
calValid = false;
|
calValid = false;
|
||||||
|
cal.resetErrorTerms();
|
||||||
emit CalibrationDisabled();
|
emit CalibrationDisabled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -902,3 +948,11 @@ void VNA::UpdateCalWidget()
|
|||||||
calLabel->setStyleSheet(getCalStyle());
|
calLabel->setStyleSheet(getCalStyle());
|
||||||
calLabel->setToolTip(getCalToolTip());
|
calLabel->setToolTip(getCalToolTip());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VNA::EnableDeembedding(bool enable)
|
||||||
|
{
|
||||||
|
deembedding_active = enable;
|
||||||
|
enableDeembeddingAction->blockSignals(true);
|
||||||
|
enableDeembeddingAction->setChecked(enable);
|
||||||
|
enableDeembeddingAction->blockSignals(false);
|
||||||
|
}
|
||||||
|
@ -58,7 +58,9 @@ private:
|
|||||||
void StopSweep();
|
void StopSweep();
|
||||||
void StartCalibrationDialog(Calibration::Type type = Calibration::Type::None);
|
void StartCalibrationDialog(Calibration::Type type = Calibration::Type::None);
|
||||||
void UpdateCalWidget();
|
void UpdateCalWidget();
|
||||||
|
private slots:
|
||||||
|
void EnableDeembedding(bool enable);
|
||||||
|
private:
|
||||||
Protocol::SweepSettings settings;
|
Protocol::SweepSettings settings;
|
||||||
unsigned int averages;
|
unsigned int averages;
|
||||||
TraceModel traceModel;
|
TraceModel traceModel;
|
||||||
@ -82,6 +84,8 @@ private:
|
|||||||
QAction *saveCal;
|
QAction *saveCal;
|
||||||
|
|
||||||
Deembedding deembedding;
|
Deembedding deembedding;
|
||||||
|
QAction *enableDeembeddingAction;
|
||||||
|
bool deembedding_active;
|
||||||
|
|
||||||
// Status Labels
|
// Status Labels
|
||||||
QLabel *lAverages;
|
QLabel *lAverages;
|
||||||
|
1001
Software/PC_Application/uncal.s2p
Normal file
1001
Software/PC_Application/uncal.s2p
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user