WIP: make de-embedding and calibration work with arbitrary number of ports
This commit is contained in:
parent
8301448343
commit
9cf76c9681
@ -45,6 +45,7 @@ QString Calibration::TypeToString(Calibration::Type type)
|
|||||||
switch(type) {
|
switch(type) {
|
||||||
case Type::None: return "None";
|
case Type::None: return "None";
|
||||||
case Type::SOLT: return "SOLT";
|
case Type::SOLT: return "SOLT";
|
||||||
|
case Type::ThroughNormalization: return "ThroughNormalization";
|
||||||
case Type::Last: return "Invalid";
|
case Type::Last: return "Invalid";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,6 +135,18 @@ void Calibration::correctMeasurement(VirtualDevice::VNAMeasurement &d)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Calibration::correctTraces(std::map<QString, Trace *> traceSet)
|
||||||
|
{
|
||||||
|
auto points = Trace::assembleDatapoints(traceSet);
|
||||||
|
if(points.size()) {
|
||||||
|
// succeeded in assembling datapoints
|
||||||
|
for(auto &p : points) {
|
||||||
|
correctMeasurement(p);
|
||||||
|
}
|
||||||
|
Trace::fillFromDatapoints(traceSet, points);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Calibration::edit()
|
void Calibration::edit()
|
||||||
{
|
{
|
||||||
auto d = new QDialog();
|
auto d = new QDialog();
|
||||||
@ -390,8 +403,7 @@ CalibrationMeasurement::Base *Calibration::newMeasurement(CalibrationMeasurement
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
Calibration::Point Calibration::computeSOLT(double f)
|
Calibration::Point Calibration::createInitializedPoint(double f) {
|
||||||
{
|
|
||||||
Point point;
|
Point point;
|
||||||
point.frequency = f;
|
point.frequency = f;
|
||||||
// resize vectors
|
// resize vectors
|
||||||
@ -405,6 +417,12 @@ Calibration::Point Calibration::computeSOLT(double f)
|
|||||||
fill(point.L.begin(), point.L.end(), vector<complex<double>>(caltype.usedPorts.size()));
|
fill(point.L.begin(), point.L.end(), vector<complex<double>>(caltype.usedPorts.size()));
|
||||||
fill(point.T.begin(), point.T.end(), vector<complex<double>>(caltype.usedPorts.size()));
|
fill(point.T.begin(), point.T.end(), vector<complex<double>>(caltype.usedPorts.size()));
|
||||||
fill(point.I.begin(), point.I.end(), vector<complex<double>>(caltype.usedPorts.size()));
|
fill(point.I.begin(), point.I.end(), vector<complex<double>>(caltype.usedPorts.size()));
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
Calibration::Point Calibration::computeSOLT(double f)
|
||||||
|
{
|
||||||
|
Point point = createInitializedPoint(f);
|
||||||
|
|
||||||
// Calculate SOL coefficients
|
// Calculate SOL coefficients
|
||||||
for(unsigned int i=0;i<caltype.usedPorts.size();i++) {
|
for(unsigned int i=0;i<caltype.usedPorts.size();i++) {
|
||||||
@ -464,6 +482,47 @@ Calibration::Point Calibration::computeSOLT(double f)
|
|||||||
return point;
|
return point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Calibration::Point Calibration::computeThroughNormalization(double f)
|
||||||
|
{
|
||||||
|
Point point = createInitializedPoint(f);
|
||||||
|
|
||||||
|
// Calculate SOL coefficients
|
||||||
|
for(unsigned int i=0;i<caltype.usedPorts.size();i++) {
|
||||||
|
// use ideal coefficients
|
||||||
|
point.D[i] = 0.0;
|
||||||
|
point.S[i] = 0.0;
|
||||||
|
point.R[i] = 1.0;
|
||||||
|
}
|
||||||
|
// calculate forward match and transmission
|
||||||
|
for(unsigned int i=0;i<caltype.usedPorts.size();i++) {
|
||||||
|
for(unsigned int j=0;j<caltype.usedPorts.size();j++) {
|
||||||
|
if(i == j) {
|
||||||
|
// this is the exciting port, SOL error box used here
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto p1 = caltype.usedPorts[i];
|
||||||
|
auto p2 = caltype.usedPorts[j];
|
||||||
|
// grab measurement and calkit through definitions
|
||||||
|
auto throughForward = static_cast<CalibrationMeasurement::Through*>(findMeasurement(CalibrationMeasurement::Base::Type::Through, p1, p2));
|
||||||
|
auto throughReverse = static_cast<CalibrationMeasurement::Through*>(findMeasurement(CalibrationMeasurement::Base::Type::Through, p2, p1));
|
||||||
|
complex<double> S11, S21;
|
||||||
|
Sparam Sideal;
|
||||||
|
if(throughForward) {
|
||||||
|
S21 = throughForward->getMeasured(f).m21;
|
||||||
|
Sideal = throughForward->getActual(f);
|
||||||
|
} else if(throughReverse) {
|
||||||
|
S21 = throughReverse->getMeasured(f).m12;
|
||||||
|
Sideal = throughReverse->getActual(f);
|
||||||
|
swap(Sideal.m12, Sideal.m21);
|
||||||
|
}
|
||||||
|
point.L[i][j] = 0.0;
|
||||||
|
point.T[i][j] = S21 / Sideal.m21;
|
||||||
|
point.I[i][j] = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
Calibration::CalType Calibration::getCaltype() const
|
Calibration::CalType Calibration::getCaltype() const
|
||||||
{
|
{
|
||||||
return caltype;
|
return caltype;
|
||||||
@ -504,12 +563,151 @@ Calibration::InterpolationType Calibration::getInterpolation(double f_start, dou
|
|||||||
|
|
||||||
std::vector<Trace *> Calibration::getErrorTermTraces()
|
std::vector<Trace *> Calibration::getErrorTermTraces()
|
||||||
{
|
{
|
||||||
return vector<Trace*>(); // TODO
|
vector<Trace*> ret;
|
||||||
|
if(points.size() == 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
for(unsigned int i=0;i<caltype.usedPorts.size();i++) {
|
||||||
|
auto p = caltype.usedPorts[i];
|
||||||
|
auto tDir = new Trace("Directivity_Port"+QString::number(p));
|
||||||
|
tDir->setReflection(true);
|
||||||
|
tDir->setCalibration();
|
||||||
|
auto tSM = new Trace("SourceMatch_Port"+QString::number(p));
|
||||||
|
tSM->setReflection(true);
|
||||||
|
tSM->setCalibration();
|
||||||
|
auto tRT = new Trace("ReflectionTracking_Port"+QString::number(p));
|
||||||
|
tRT->setReflection(false);
|
||||||
|
tRT->setCalibration();
|
||||||
|
for(auto p : points) {
|
||||||
|
Trace::Data td;
|
||||||
|
td.x = p.frequency;
|
||||||
|
td.y = p.D[i];
|
||||||
|
tDir->addData(td, Trace::DataType::Frequency);
|
||||||
|
td.y = p.S[i];
|
||||||
|
tSM->addData(td, Trace::DataType::Frequency);
|
||||||
|
td.y = p.R[i];
|
||||||
|
tRT->addData(td, Trace::DataType::Frequency);
|
||||||
|
}
|
||||||
|
ret.push_back(tDir);
|
||||||
|
ret.push_back(tSM);
|
||||||
|
ret.push_back(tRT);
|
||||||
|
for(unsigned int j=0;j<caltype.usedPorts.size();j++) {
|
||||||
|
if(i==j) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto p2 = caltype.usedPorts[j];
|
||||||
|
auto tRM = new Trace("ReceiverMatch_"+QString::number(p)+QString::number(p2));
|
||||||
|
tRM->setReflection(true);
|
||||||
|
tRM->setCalibration();
|
||||||
|
auto tTT = new Trace("TransmissionTracking_"+QString::number(p)+QString::number(p2));
|
||||||
|
tTT->setReflection(false);
|
||||||
|
tTT->setCalibration();
|
||||||
|
auto tTI = new Trace("TransmissionIsolation_"+QString::number(p)+QString::number(p2));
|
||||||
|
tTI->setReflection(false);
|
||||||
|
tTI->setCalibration();
|
||||||
|
for(auto p : points) {
|
||||||
|
Trace::Data td;
|
||||||
|
td.x = p.frequency;
|
||||||
|
td.y = p.L[i][j];
|
||||||
|
tRM->addData(td, Trace::DataType::Frequency);
|
||||||
|
td.y = p.T[i][j];
|
||||||
|
tTT->addData(td, Trace::DataType::Frequency);
|
||||||
|
td.y = p.I[i][j];
|
||||||
|
tTI->addData(td, Trace::DataType::Frequency);
|
||||||
|
}
|
||||||
|
ret.push_back(tRM);
|
||||||
|
ret.push_back(tTT);
|
||||||
|
ret.push_back(tTI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Trace *> Calibration::getMeasurementTraces()
|
std::vector<Trace *> Calibration::getMeasurementTraces()
|
||||||
{
|
{
|
||||||
return vector<Trace*>(); // TODO
|
vector<Trace*> ret;
|
||||||
|
for(auto m : measurements) {
|
||||||
|
switch(m->getType()) {
|
||||||
|
case CalibrationMeasurement::Base::Type::Open:
|
||||||
|
case CalibrationMeasurement::Base::Type::Short:
|
||||||
|
case CalibrationMeasurement::Base::Type::Load: {
|
||||||
|
auto onePort = static_cast<CalibrationMeasurement::OnePort*>(m);
|
||||||
|
auto t = new Trace(CalibrationMeasurement::Base::TypeToString(onePort->getType())+"_Port"+QString::number(onePort->getPort()));
|
||||||
|
t->setCalibration();
|
||||||
|
t->setReflection(true);
|
||||||
|
for(auto d : onePort->getPoints()) {
|
||||||
|
Trace::Data td;
|
||||||
|
td.x = d.frequency;
|
||||||
|
td.y = d.S;
|
||||||
|
t->addData(td, Trace::DataType::Frequency);
|
||||||
|
}
|
||||||
|
ret.push_back(t);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CalibrationMeasurement::Base::Type::Through: {
|
||||||
|
auto twoPort = static_cast<CalibrationMeasurement::TwoPort*>(m);
|
||||||
|
auto ts11 = new Trace(CalibrationMeasurement::Base::TypeToString(twoPort->getType())+"_Port"+QString::number(twoPort->getPort1())+QString::number(twoPort->getPort2())+"_S11");
|
||||||
|
auto ts12 = new Trace(CalibrationMeasurement::Base::TypeToString(twoPort->getType())+"_Port"+QString::number(twoPort->getPort1())+QString::number(twoPort->getPort2())+"_S12");
|
||||||
|
auto ts21 = new Trace(CalibrationMeasurement::Base::TypeToString(twoPort->getType())+"_Port"+QString::number(twoPort->getPort1())+QString::number(twoPort->getPort2())+"_S21");
|
||||||
|
auto ts22 = new Trace(CalibrationMeasurement::Base::TypeToString(twoPort->getType())+"_Port"+QString::number(twoPort->getPort1())+QString::number(twoPort->getPort2())+"_S22");
|
||||||
|
ts11->setCalibration();
|
||||||
|
ts11->setReflection(true);
|
||||||
|
ts12->setCalibration();
|
||||||
|
ts12->setReflection(false);
|
||||||
|
ts21->setCalibration();
|
||||||
|
ts21->setReflection(false);
|
||||||
|
ts22->setCalibration();
|
||||||
|
ts22->setReflection(true);
|
||||||
|
for(auto d : twoPort->getPoints()) {
|
||||||
|
Trace::Data td;
|
||||||
|
td.x = d.frequency;
|
||||||
|
td.y = d.S.m11;
|
||||||
|
ts11->addData(td, Trace::DataType::Frequency);
|
||||||
|
td.y = d.S.m12;
|
||||||
|
ts12->addData(td, Trace::DataType::Frequency);
|
||||||
|
td.y = d.S.m21;
|
||||||
|
ts21->addData(td, Trace::DataType::Frequency);
|
||||||
|
td.y = d.S.m22;
|
||||||
|
ts22->addData(td, Trace::DataType::Frequency);
|
||||||
|
}
|
||||||
|
ret.push_back(ts11);
|
||||||
|
ret.push_back(ts12);
|
||||||
|
ret.push_back(ts21);
|
||||||
|
ret.push_back(ts22);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CalibrationMeasurement::Base::Type::Isolation: {
|
||||||
|
auto iso = static_cast<CalibrationMeasurement::Isolation*>(m);
|
||||||
|
int ports = iso->getPoints()[0].S.size();
|
||||||
|
// Create the traces
|
||||||
|
vector<vector<Trace*>> traces;
|
||||||
|
traces.resize(ports);
|
||||||
|
for(int i=0;i<ports;i++) {
|
||||||
|
for(int j=0;j<ports;j++) {
|
||||||
|
auto t = new Trace(CalibrationMeasurement::Base::TypeToString(iso->getType())+"_S"+QString::number(i+1)+QString::number(j+1));
|
||||||
|
t->setCalibration();
|
||||||
|
t->setReflection(i==j);
|
||||||
|
traces[i].push_back(t);
|
||||||
|
// also add to main return vector
|
||||||
|
ret.push_back(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fill the traces
|
||||||
|
for(auto p : iso->getPoints()) {
|
||||||
|
Trace::Data td;
|
||||||
|
td.x = p.frequency;
|
||||||
|
for(int i=0;i<p.S.size();i++) {
|
||||||
|
for(int j=0;j<p.S[i].size();j++) {
|
||||||
|
td.y = p.S[i][j];
|
||||||
|
traces[i][j]->addData(td, Trace::DataType::Frequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Calibration::getCurrentCalibrationFile()
|
QString Calibration::getCurrentCalibrationFile()
|
||||||
@ -735,15 +933,15 @@ std::vector<Calibration::Type> Calibration::getTypes()
|
|||||||
|
|
||||||
bool Calibration::canCompute(Calibration::CalType type, double *startFreq, double *stopFreq, int *points)
|
bool Calibration::canCompute(Calibration::CalType type, double *startFreq, double *stopFreq, int *points)
|
||||||
{
|
{
|
||||||
switch(type.type) {
|
|
||||||
case Type::None:
|
|
||||||
return true; // Always possible to reset the calibration
|
|
||||||
case Type::SOLT: {
|
|
||||||
using RequiredMeasurements = struct {
|
using RequiredMeasurements = struct {
|
||||||
CalibrationMeasurement::Base::Type type;
|
CalibrationMeasurement::Base::Type type;
|
||||||
int port1, port2;
|
int port1, port2;
|
||||||
};
|
};
|
||||||
vector<RequiredMeasurements> required;
|
vector<RequiredMeasurements> required;
|
||||||
|
switch(type.type) {
|
||||||
|
case Type::None:
|
||||||
|
return true; // Always possible to reset the calibration
|
||||||
|
case Type::SOLT:
|
||||||
// SOL measurements for every port
|
// SOL measurements for every port
|
||||||
for(auto p : type.usedPorts) {
|
for(auto p : type.usedPorts) {
|
||||||
required.push_back({.type = CalibrationMeasurement::Base::Type::Short, .port1 = p});
|
required.push_back({.type = CalibrationMeasurement::Base::Type::Short, .port1 = p});
|
||||||
@ -756,6 +954,17 @@ bool Calibration::canCompute(Calibration::CalType type, double *startFreq, doubl
|
|||||||
required.push_back({.type = CalibrationMeasurement::Base::Type::Through, .port1 = i, .port2 = j});
|
required.push_back({.type = CalibrationMeasurement::Base::Type::Through, .port1 = i, .port2 = j});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case Type::ThroughNormalization:
|
||||||
|
// through measurements between all ports
|
||||||
|
for(int i=1;i<=type.usedPorts.size();i++) {
|
||||||
|
for(int j=i+1;j<=type.usedPorts.size();j++) {
|
||||||
|
required.push_back({.type = CalibrationMeasurement::Base::Type::Through, .port1 = i, .port2 = j});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(required.size() > 0) {
|
||||||
vector<CalibrationMeasurement::Base*> foundMeasurements;
|
vector<CalibrationMeasurement::Base*> foundMeasurements;
|
||||||
for(auto m : required) {
|
for(auto m : required) {
|
||||||
auto meas = findMeasurement(m.type, m.port1, m.port2);
|
auto meas = findMeasurement(m.type, m.port1, m.port2);
|
||||||
@ -767,8 +976,6 @@ bool Calibration::canCompute(Calibration::CalType type, double *startFreq, doubl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hasFrequencyOverlap(foundMeasurements, startFreq, stopFreq, points);
|
return hasFrequencyOverlap(foundMeasurements, startFreq, stopFreq, points);
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -816,6 +1023,7 @@ int Calibration::minimumPorts(Calibration::Type type)
|
|||||||
{
|
{
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case Type::SOLT: return 1;
|
case Type::SOLT: return 1;
|
||||||
|
case Type::ThroughNormalization: return 2;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ public:
|
|||||||
enum class Type {
|
enum class Type {
|
||||||
None,
|
None,
|
||||||
SOLT,
|
SOLT,
|
||||||
|
ThroughNormalization,
|
||||||
Last,
|
Last,
|
||||||
};
|
};
|
||||||
class CalType {
|
class CalType {
|
||||||
@ -36,6 +37,7 @@ public:
|
|||||||
|
|
||||||
// Applies calculated calibration coefficients to measurement data
|
// Applies calculated calibration coefficients to measurement data
|
||||||
void correctMeasurement(VirtualDevice::VNAMeasurement &d);
|
void correctMeasurement(VirtualDevice::VNAMeasurement &d);
|
||||||
|
void correctTraces(std::map<QString, Trace*> traceSet);
|
||||||
|
|
||||||
// Starts the calibration edit dialog, allowing the user to make/delete measurements
|
// Starts the calibration edit dialog, allowing the user to make/delete measurements
|
||||||
void edit();
|
void edit();
|
||||||
@ -123,8 +125,8 @@ private:
|
|||||||
public:
|
public:
|
||||||
double frequency;
|
double frequency;
|
||||||
std::vector<std::complex<double>> D; // Directivity
|
std::vector<std::complex<double>> D; // Directivity
|
||||||
std::vector<std::complex<double>> R; // Source Match
|
std::vector<std::complex<double>> R; // Reflection tracking
|
||||||
std::vector<std::complex<double>> S; // Reflection tracking
|
std::vector<std::complex<double>> S; // Source Match
|
||||||
std::vector<std::vector<std::complex<double>>> L; // Receiver Match
|
std::vector<std::vector<std::complex<double>>> L; // Receiver Match
|
||||||
std::vector<std::vector<std::complex<double>>> T; // Transmission tracking
|
std::vector<std::vector<std::complex<double>>> T; // Transmission tracking
|
||||||
std::vector<std::vector<std::complex<double>>> I; // Transmission isolation
|
std::vector<std::vector<std::complex<double>>> I; // Transmission isolation
|
||||||
@ -132,7 +134,9 @@ private:
|
|||||||
};
|
};
|
||||||
std::vector<Point> points;
|
std::vector<Point> points;
|
||||||
|
|
||||||
|
Point createInitializedPoint(double f);
|
||||||
Point computeSOLT(double f);
|
Point computeSOLT(double f);
|
||||||
|
Point computeThroughNormalization(double f);
|
||||||
|
|
||||||
std::vector<CalibrationMeasurement::Base*> measurements;
|
std::vector<CalibrationMeasurement::Base*> measurements;
|
||||||
|
|
||||||
|
@ -328,6 +328,11 @@ void CalibrationMeasurement::OnePort::setPort(int p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<CalibrationMeasurement::OnePort::Point> CalibrationMeasurement::OnePort::getPoints() const
|
||||||
|
{
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
double CalibrationMeasurement::TwoPort::minFreq()
|
double CalibrationMeasurement::TwoPort::minFreq()
|
||||||
{
|
{
|
||||||
if(points.size() > 0) {
|
if(points.size() > 0) {
|
||||||
@ -529,6 +534,11 @@ void CalibrationMeasurement::TwoPort::setReverseStandard(bool reverse)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<CalibrationMeasurement::TwoPort::Point> CalibrationMeasurement::TwoPort::getPoints() const
|
||||||
|
{
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
int CalibrationMeasurement::TwoPort::getPort1() const
|
int CalibrationMeasurement::TwoPort::getPort1() const
|
||||||
{
|
{
|
||||||
return port1;
|
return port1;
|
||||||
@ -658,3 +668,8 @@ std::complex<double> CalibrationMeasurement::Isolation::getMeasured(double frequ
|
|||||||
return p.S[portRcv][portSrc];
|
return p.S[portRcv][portSrc];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<CalibrationMeasurement::Isolation::Point> CalibrationMeasurement::Isolation::getPoints() const
|
||||||
|
{
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifndef CALIBRATIONMEASUREMENT_H
|
#ifndef CALIBRATIONMEASUREMENT_H
|
||||||
#define CALIBRATIONMEASUREMENT_H
|
#define CALIBRATIONMEASUREMENT_H
|
||||||
|
|
||||||
#include "calstandard.h"
|
#include "calstandard.h"
|
||||||
@ -83,6 +83,13 @@ public:
|
|||||||
virtual nlohmann::json toJSON() override;
|
virtual nlohmann::json toJSON() override;
|
||||||
virtual void fromJSON(nlohmann::json j) override;
|
virtual void fromJSON(nlohmann::json j) override;
|
||||||
|
|
||||||
|
class Point {
|
||||||
|
public:
|
||||||
|
double frequency;
|
||||||
|
std::complex<double> S;
|
||||||
|
};
|
||||||
|
std::vector<Point> getPoints() const;
|
||||||
|
|
||||||
std::complex<double> getMeasured(double frequency);
|
std::complex<double> getMeasured(double frequency);
|
||||||
std::complex<double> getActual(double frequency);
|
std::complex<double> getActual(double frequency);
|
||||||
|
|
||||||
@ -95,11 +102,6 @@ signals:
|
|||||||
void portChanged(int p);
|
void portChanged(int p);
|
||||||
protected:
|
protected:
|
||||||
int port;
|
int port;
|
||||||
class Point {
|
|
||||||
public:
|
|
||||||
double frequency;
|
|
||||||
std::complex<double> S;
|
|
||||||
};
|
|
||||||
std::vector<Point> points;
|
std::vector<Point> points;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -156,12 +158,20 @@ public:
|
|||||||
virtual nlohmann::json toJSON() override;
|
virtual nlohmann::json toJSON() override;
|
||||||
virtual void fromJSON(nlohmann::json j) override;
|
virtual void fromJSON(nlohmann::json j) override;
|
||||||
|
|
||||||
|
class Point {
|
||||||
|
public:
|
||||||
|
double frequency;
|
||||||
|
Sparam S;
|
||||||
|
};
|
||||||
|
std::vector<Point> getPoints() const;
|
||||||
|
|
||||||
Sparam getMeasured(double frequency);
|
Sparam getMeasured(double frequency);
|
||||||
Sparam getActual(double frequency);
|
Sparam getActual(double frequency);
|
||||||
|
|
||||||
int getPort1() const;
|
int getPort1() const;
|
||||||
int getPort2() const;
|
int getPort2() const;
|
||||||
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setPort1(int p);
|
void setPort1(int p);
|
||||||
void setPort2(int p);
|
void setPort2(int p);
|
||||||
@ -174,11 +184,6 @@ signals:
|
|||||||
protected:
|
protected:
|
||||||
int port1, port2;
|
int port1, port2;
|
||||||
bool reverseStandard; // Set to true if standard is defined with ports swapped
|
bool reverseStandard; // Set to true if standard is defined with ports swapped
|
||||||
class Point {
|
|
||||||
public:
|
|
||||||
double frequency;
|
|
||||||
Sparam S;
|
|
||||||
};
|
|
||||||
std::vector<Point> points;
|
std::vector<Point> points;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -211,17 +216,19 @@ public:
|
|||||||
virtual nlohmann::json toJSON() override;
|
virtual nlohmann::json toJSON() override;
|
||||||
virtual void fromJSON(nlohmann::json j) override;
|
virtual void fromJSON(nlohmann::json j) override;
|
||||||
|
|
||||||
|
class Point {
|
||||||
|
public:
|
||||||
|
double frequency;
|
||||||
|
std::vector<std::vector<std::complex<double>>> S;
|
||||||
|
};
|
||||||
|
std::vector<Point> getPoints() const;
|
||||||
|
|
||||||
std::complex<double> getMeasured(double frequency, unsigned int portRcv, unsigned int portSrc);
|
std::complex<double> getMeasured(double frequency, unsigned int portRcv, unsigned int portSrc);
|
||||||
|
|
||||||
virtual std::set<CalStandard::Virtual::Type> supportedStandardTypes() override {return {};}
|
virtual std::set<CalStandard::Virtual::Type> supportedStandardTypes() override {return {};}
|
||||||
virtual Type getType() override {return Type::Isolation;}
|
virtual Type getType() override {return Type::Isolation;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class Point {
|
|
||||||
public:
|
|
||||||
double frequency;
|
|
||||||
std::vector<std::vector<std::complex<double>>> S;
|
|
||||||
};
|
|
||||||
std::vector<Point> points;
|
std::vector<Point> points;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,13 +7,12 @@ ManualCalibrationDialog::ManualCalibrationDialog(const TraceModel &model, Calibr
|
|||||||
ui(new Ui::ManualCalibrationDialog)
|
ui(new Ui::ManualCalibrationDialog)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
auto traceSelector = new SparamTraceSelector(model, 2);
|
auto traceSelector = new SparamTraceSelector(model, cal->getCaltype().usedPorts);
|
||||||
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);
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=]() {
|
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=]() {
|
||||||
auto t = traceSelector->getTraces();
|
cal->correctTraces(traceSelector->getTraces());
|
||||||
// cal->correctTraces(*t[0], *t[1], *t[2], *t[3]); // TODO
|
|
||||||
accept();
|
accept();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,42 +5,39 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
SparamTraceSelector::SparamTraceSelector(const TraceModel &model, unsigned int num_ports, bool empty_allowed, std::set<unsigned int> skip)
|
SparamTraceSelector::SparamTraceSelector(const TraceModel &model, std::vector<int> used_ports, bool empty_allowed)
|
||||||
: model(model),
|
: model(model),
|
||||||
num_ports(num_ports),
|
used_ports(used_ports),
|
||||||
empty_allowed(empty_allowed)
|
empty_allowed(empty_allowed)
|
||||||
{
|
{
|
||||||
// Create comboboxes
|
createGUI();
|
||||||
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();
|
setInitialChoices();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Trace*> SparamTraceSelector::getTraces()
|
SparamTraceSelector::SparamTraceSelector(const TraceModel &model, std::set<int> used_ports, bool empty_allowed)
|
||||||
|
: model(model),
|
||||||
|
empty_allowed(empty_allowed)
|
||||||
{
|
{
|
||||||
vector<Trace*> ret;
|
// create vector from set
|
||||||
for(auto b : boxes) {
|
std::copy(used_ports.begin(), used_ports.end(), std::back_inserter(this->used_ports));
|
||||||
|
createGUI();
|
||||||
|
setInitialChoices();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<QString, Trace*> SparamTraceSelector::getTraces()
|
||||||
|
{
|
||||||
|
std::map<QString, Trace*> ret;
|
||||||
|
for(unsigned int i=0;i<used_ports.size();i++) {
|
||||||
|
for(unsigned int j=0;j<used_ports.size();j++) {
|
||||||
|
auto b = boxes[i*used_ports.size()+j];
|
||||||
|
Trace *t;
|
||||||
if(b->currentIndex() == 0) {
|
if(b->currentIndex() == 0) {
|
||||||
ret.push_back(nullptr);
|
t = nullptr;
|
||||||
} else {
|
} else {
|
||||||
auto trace = qvariant_cast<Trace*>(b->itemData(b->currentIndex()));
|
t = qvariant_cast<Trace*>(b->itemData(b->currentIndex()));
|
||||||
ret.push_back(trace);
|
}
|
||||||
|
QString name = "S"+QString::number(used_ports[i])+QString::number(used_ports[j]);
|
||||||
|
ret[name] = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -48,7 +45,7 @@ std::vector<Trace*> SparamTraceSelector::getTraces()
|
|||||||
|
|
||||||
void SparamTraceSelector::setInitialChoices()
|
void SparamTraceSelector::setInitialChoices()
|
||||||
{
|
{
|
||||||
for(unsigned int i=0;i<num_ports*num_ports;i++) {
|
for(unsigned int i=0;i<used_ports.size()*used_ports.size();i++) {
|
||||||
boxes[i]->blockSignals(true);
|
boxes[i]->blockSignals(true);
|
||||||
boxes[i]->clear();
|
boxes[i]->clear();
|
||||||
boxes[i]->addItem("None");
|
boxes[i]->addItem("None");
|
||||||
@ -61,7 +58,7 @@ void SparamTraceSelector::setInitialChoices()
|
|||||||
// can't select empty traces
|
// can't select empty traces
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool reflectionRequired = i%(num_ports+1) == 0 ? true : false;
|
bool reflectionRequired = i%(used_ports.size()+1) == 0 ? true : false;
|
||||||
if(reflectionRequired != t->isReflection()) {
|
if(reflectionRequired != t->isReflection()) {
|
||||||
// invalid S parameter
|
// invalid S parameter
|
||||||
continue;
|
continue;
|
||||||
@ -106,7 +103,7 @@ void SparamTraceSelector::traceSelectionChanged(QComboBox *cb)
|
|||||||
text.chop(2);
|
text.chop(2);
|
||||||
if(text.endsWith("S")) {
|
if(text.endsWith("S")) {
|
||||||
// tracename ended in Sxx, probably other traces with matching prefix available
|
// tracename ended in Sxx, probably other traces with matching prefix available
|
||||||
for(unsigned int i=0;i<num_ports*num_ports;i++) {
|
for(unsigned int i=0;i<used_ports.size()*used_ports.size();i++) {
|
||||||
auto b = boxes[i];
|
auto b = boxes[i];
|
||||||
if(b == cb) {
|
if(b == cb) {
|
||||||
// skip this box
|
// skip this box
|
||||||
@ -115,7 +112,7 @@ 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/num_ports+1)+QString::number(i%num_ports+1);
|
QString expectedSparam = QString::number(i/used_ports.size()+1)+QString::number(i%used_ports.size()+1);
|
||||||
if(!candidate.endsWith(expectedSparam)) {
|
if(!candidate.endsWith(expectedSparam)) {
|
||||||
// wrong S parameter, skip
|
// wrong S parameter, skip
|
||||||
continue;
|
continue;
|
||||||
@ -170,3 +167,21 @@ void SparamTraceSelector::traceSelectionChanged(QComboBox *cb)
|
|||||||
emit selectionValid(valid);
|
emit selectionValid(valid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SparamTraceSelector::createGUI()
|
||||||
|
{
|
||||||
|
// Create comboboxes
|
||||||
|
auto layout = new QFormLayout;
|
||||||
|
setLayout(layout);
|
||||||
|
for(unsigned int i=0;i<used_ports.size();i++) {
|
||||||
|
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 box = new QComboBox();
|
||||||
|
connect(box, qOverload<int>(&QComboBox::currentIndexChanged), [=](int) {
|
||||||
|
traceSelectionChanged(box);
|
||||||
|
});
|
||||||
|
boxes.push_back(box);
|
||||||
|
layout->addRow(label, box);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "tracemodel.h"
|
#include "tracemodel.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
|
||||||
@ -11,12 +13,13 @@ class SparamTraceSelector : public QWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SparamTraceSelector(const TraceModel &model, unsigned int num_ports, bool empty_allowed = false, std::set<unsigned int> skip = {});
|
SparamTraceSelector(const TraceModel &model, std::vector<int> used_ports, bool empty_allowed = false);
|
||||||
|
SparamTraceSelector(const TraceModel &model, std::set<int> used_ports, bool empty_allowed = false);
|
||||||
|
|
||||||
bool isValid();
|
bool isValid();
|
||||||
|
|
||||||
std::vector<Trace*> getTraces();
|
std::map<QString, Trace*> getTraces();
|
||||||
unsigned int getPoints() { return points;};
|
unsigned int getPoints() { return points;}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void selectionValid(bool valid);
|
void selectionValid(bool valid);
|
||||||
@ -24,12 +27,13 @@ signals:
|
|||||||
private:
|
private:
|
||||||
void setInitialChoices();
|
void setInitialChoices();
|
||||||
void traceSelectionChanged(QComboBox *cb);
|
void traceSelectionChanged(QComboBox *cb);
|
||||||
|
void createGUI();
|
||||||
|
|
||||||
const TraceModel &model;
|
const TraceModel &model;
|
||||||
std::vector<QComboBox*> boxes;
|
std::vector<QComboBox*> boxes;
|
||||||
unsigned int num_ports;
|
|
||||||
bool empty_allowed;
|
bool empty_allowed;
|
||||||
|
|
||||||
|
std::vector<int> used_ports;
|
||||||
unsigned int points;
|
unsigned int points;
|
||||||
double minFreq, maxFreq;
|
double minFreq, maxFreq;
|
||||||
bool valid;
|
bool valid;
|
||||||
|
@ -260,24 +260,24 @@ QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
|
|||||||
return lastTraceName;
|
return lastTraceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Trace::fillFromDatapoints(Trace &S11, Trace &S12, Trace &S21, Trace &S22, const std::vector<VirtualDevice::VNAMeasurement> &data)
|
void Trace::fillFromDatapoints(std::map<QString, Trace *> traceSet, const std::vector<VirtualDevice::VNAMeasurement> &data)
|
||||||
{
|
{
|
||||||
S11.clear();
|
// remove all previous points
|
||||||
S12.clear();
|
for(auto m : traceSet) {
|
||||||
S21.clear();
|
m.second->clear();
|
||||||
S22.clear();
|
}
|
||||||
|
// add new points to traces
|
||||||
for(auto d : data) {
|
for(auto d : data) {
|
||||||
Trace::Data td;
|
Trace::Data td;
|
||||||
auto S = d.toSparam(1, 2);
|
auto S = d.toSparam(1, 2);
|
||||||
td.x = d.frequency;
|
td.x = d.frequency;
|
||||||
td.y = S.m11;
|
for(auto m : d.measurements) {
|
||||||
S11.addData(td, DataType::Frequency);
|
td.y = m.second;
|
||||||
td.y = S.m12;
|
QString measurement = m.first;
|
||||||
S12.addData(td, DataType::Frequency);
|
if(traceSet.count(measurement)) {
|
||||||
td.y = S.m21;
|
traceSet[measurement]->addData(td, DataType::Frequency);
|
||||||
S21.addData(td, DataType::Frequency);
|
}
|
||||||
td.y = S.m22;
|
}
|
||||||
S22.addData(td, DataType::Frequency);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -894,20 +894,16 @@ std::vector<Trace *> Trace::createFromCSV(CSV &csv)
|
|||||||
return traces;
|
return traces;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VirtualDevice::VNAMeasurement> Trace::assembleDatapoints(const Trace &S11, const Trace &S12, const Trace &S21, const Trace &S22)
|
std::vector<VirtualDevice::VNAMeasurement> Trace::assembleDatapoints(std::map<QString, Trace *> traceSet)
|
||||||
{
|
{
|
||||||
vector<VirtualDevice::VNAMeasurement> ret;
|
vector<VirtualDevice::VNAMeasurement> ret;
|
||||||
|
|
||||||
// Sanity check traces
|
// Sanity check traces
|
||||||
unsigned int samples = S11.size();
|
unsigned int samples = traceSet.begin()->second->size();
|
||||||
auto impedance = S11.getReferenceImpedance();
|
auto impedance = traceSet.begin()->second->getReferenceImpedance();
|
||||||
vector<const Trace*> traces;
|
|
||||||
traces.push_back(&S11);
|
|
||||||
traces.push_back(&S12);
|
|
||||||
traces.push_back(&S21);
|
|
||||||
traces.push_back(&S22);
|
|
||||||
vector<double> freqs;
|
vector<double> freqs;
|
||||||
for(const auto t : traces) {
|
for(auto m : traceSet) {
|
||||||
|
const Trace *t = m.second;
|
||||||
if(t->size() != samples) {
|
if(t->size() != samples) {
|
||||||
qWarning() << "Selected traces do not have the same size";
|
qWarning() << "Selected traces do not have the same size";
|
||||||
return ret;
|
return ret;
|
||||||
@ -939,10 +935,11 @@ std::vector<VirtualDevice::VNAMeasurement> Trace::assembleDatapoints(const Trace
|
|||||||
// Checks passed, assemble datapoints
|
// Checks passed, assemble datapoints
|
||||||
for(unsigned int i=0;i<samples;i++) {
|
for(unsigned int i=0;i<samples;i++) {
|
||||||
VirtualDevice::VNAMeasurement d;
|
VirtualDevice::VNAMeasurement d;
|
||||||
d.measurements["S11"] = S11.sample(i).y;
|
for(auto m : traceSet) {
|
||||||
d.measurements["S12"] = S12.sample(i).y;
|
QString measurement = m.first;
|
||||||
d.measurements["S21"] = S21.sample(i).y;
|
const Trace *t = m.second;
|
||||||
d.measurements["S22"] = S22.sample(i).y;
|
d.measurements[measurement] = t->sample(i).y;
|
||||||
|
}
|
||||||
d.pointNum = i;
|
d.pointNum = i;
|
||||||
d.frequency = freqs[i];
|
d.frequency = freqs[i];
|
||||||
ret.push_back(d);
|
ret.push_back(d);
|
||||||
|
@ -49,7 +49,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<VirtualDevice::VNAMeasurement> &data);
|
static void fillFromDatapoints(std::map<QString, Trace*> traceSet, const std::vector<VirtualDevice::VNAMeasurement> &data);
|
||||||
void fromLivedata(LivedataType type, QString param);
|
void fromLivedata(LivedataType type, QString param);
|
||||||
void fromMath();
|
void fromMath();
|
||||||
QString name() { return _name; }
|
QString name() { return _name; }
|
||||||
@ -137,7 +137,7 @@ public:
|
|||||||
|
|
||||||
// Assembles datapoints as received from the VNA from four S parameter traces. Requires that all traces are in the frequency domain,
|
// 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
|
// have the same number of samples and their samples must be at the same frequencies across all traces
|
||||||
static std::vector<VirtualDevice::VNAMeasurement> assembleDatapoints(const Trace &S11, const Trace &S12, const Trace &S21, const Trace &S22);
|
static std::vector<VirtualDevice::VNAMeasurement> assembleDatapoints(std::map<QString, Trace *> traceSet);
|
||||||
|
|
||||||
static LivedataType TypeFromString(QString s);
|
static LivedataType TypeFromString(QString s);
|
||||||
static QString TypeToString(LivedataType t);
|
static QString TypeToString(LivedataType t);
|
||||||
|
@ -232,7 +232,7 @@ void TracePolarChart::draw(QPainter &p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(dropPending) {
|
if(dropPending) {
|
||||||
// TODO adjust coords due to shifted restore
|
// adjust coords due to shifted restore
|
||||||
p.setOpacity(0.5);
|
p.setOpacity(0.5);
|
||||||
p.setBrush(Qt::white);
|
p.setBrush(Qt::white);
|
||||||
p.setPen(Qt::white);
|
p.setPen(Qt::white);
|
||||||
|
@ -328,7 +328,7 @@ void TraceSmithChart::draw(QPainter &p) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(dropPending) {
|
if(dropPending) {
|
||||||
// TODO adjust coords due to shifted restore
|
// adjust coords due to shifted restore
|
||||||
p.setOpacity(0.5);
|
p.setOpacity(0.5);
|
||||||
p.setBrush(Qt::white);
|
p.setBrush(Qt::white);
|
||||||
p.setPen(Qt::white);
|
p.setPen(Qt::white);
|
||||||
|
@ -30,7 +30,7 @@ void Deembedding::measurementCompleted()
|
|||||||
measurementUI = nullptr;
|
measurementUI = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Deembedding::startMeasurementDialog(bool S11, bool S12, bool S21, bool S22)
|
void Deembedding::startMeasurementDialog(DeembeddingOption *option)
|
||||||
{
|
{
|
||||||
measurements.clear();
|
measurements.clear();
|
||||||
measurementDialog = new QDialog;
|
measurementDialog = new QDialog;
|
||||||
@ -42,20 +42,7 @@ void Deembedding::startMeasurementDialog(bool S11, bool S12, bool S21, bool S22)
|
|||||||
});
|
});
|
||||||
|
|
||||||
// add the trace selector
|
// add the trace selector
|
||||||
set<unsigned int> skip;
|
auto traceChooser = new SparamTraceSelector(tm, option->getAffectedPorts());
|
||||||
if(!S11) {
|
|
||||||
skip.insert(0);
|
|
||||||
}
|
|
||||||
if(!S12) {
|
|
||||||
skip.insert(1);
|
|
||||||
}
|
|
||||||
if(!S21) {
|
|
||||||
skip.insert(2);
|
|
||||||
}
|
|
||||||
if(!S22) {
|
|
||||||
skip.insert(3);
|
|
||||||
}
|
|
||||||
auto traceChooser = new SparamTraceSelector(tm, 2, false, skip);
|
|
||||||
ui->horizontalLayout_2->insertWidget(0, traceChooser, 1);
|
ui->horizontalLayout_2->insertWidget(0, traceChooser, 1);
|
||||||
|
|
||||||
connect(traceChooser, &SparamTraceSelector::selectionValid, ui->buttonBox, &QDialogButtonBox::setEnabled);
|
connect(traceChooser, &SparamTraceSelector::selectionValid, ui->buttonBox, &QDialogButtonBox::setEnabled);
|
||||||
@ -70,33 +57,8 @@ void Deembedding::startMeasurementDialog(bool S11, bool S12, bool S21, bool S22)
|
|||||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){
|
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){
|
||||||
// create datapoints from individual traces
|
// create datapoints from individual traces
|
||||||
measurements.clear();
|
measurements.clear();
|
||||||
auto t = traceChooser->getTraces();
|
auto points = Trace::assembleDatapoints(traceChooser->getTraces());
|
||||||
auto S11 = t[0];
|
for(auto p : points) {
|
||||||
auto S12 = t[1];
|
|
||||||
auto S21 = t[2];
|
|
||||||
auto S22 = t[3];
|
|
||||||
for(unsigned int i=0;i<traceChooser->getPoints();i++) {
|
|
||||||
VirtualDevice::VNAMeasurement p;
|
|
||||||
p.pointNum = i;
|
|
||||||
p.Z0 = 0;
|
|
||||||
p.dBm = 0;
|
|
||||||
Sparam S;
|
|
||||||
if(S11) {
|
|
||||||
S.m11 = S11->sample(i).y;
|
|
||||||
p.frequency = S11->sample(i).x;
|
|
||||||
}
|
|
||||||
if(S12) {
|
|
||||||
S.m12 = S12->sample(i).y;
|
|
||||||
p.frequency = S11->sample(i).x;
|
|
||||||
}
|
|
||||||
if(S21) {
|
|
||||||
S.m21 = S21->sample(i).y;
|
|
||||||
p.frequency = S11->sample(i).x;
|
|
||||||
}
|
|
||||||
if(S22) {
|
|
||||||
S.m22 = S22->sample(i).y;
|
|
||||||
p.frequency = S11->sample(i).x;
|
|
||||||
}
|
|
||||||
measurements.push_back(p);
|
measurements.push_back(p);
|
||||||
}
|
}
|
||||||
measurementCompleted();
|
measurementCompleted();
|
||||||
@ -151,15 +113,15 @@ void Deembedding::Deembed(VirtualDevice::VNAMeasurement &d)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Deembedding::Deembed(Trace &S11, Trace &S12, Trace &S21, Trace &S22)
|
void Deembedding::Deembed(std::map<QString, Trace *> traceSet)
|
||||||
{
|
{
|
||||||
auto points = Trace::assembleDatapoints(S11, S12, S21, S22);
|
auto points = Trace::assembleDatapoints(traceSet);
|
||||||
if(points.size()) {
|
if(points.size()) {
|
||||||
// succeeded in assembling datapoints
|
// succeeded in assembling datapoints
|
||||||
for(auto &p : points) {
|
for(auto &p : points) {
|
||||||
Deembed(p);
|
Deembed(p);
|
||||||
}
|
}
|
||||||
Trace::fillFromDatapoints(S11, S12, S21, S22, points);
|
Trace::fillFromDatapoints(traceSet, points);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,9 +146,9 @@ void Deembedding::addOption(DeembeddingOption *option)
|
|||||||
options.erase(pos);
|
options.erase(pos);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(option, &DeembeddingOption::triggerMeasurement, [=](bool S11, bool S12, bool S21, bool S22) {
|
connect(option, &DeembeddingOption::triggerMeasurement, [=]() {
|
||||||
measuringOption = option;
|
measuringOption = option;
|
||||||
startMeasurementDialog(S11, S12, S21, S22);
|
startMeasurementDialog(option);
|
||||||
});
|
});
|
||||||
emit optionAdded();
|
emit optionAdded();
|
||||||
}
|
}
|
||||||
@ -199,6 +161,16 @@ void Deembedding::swapOptions(unsigned int index)
|
|||||||
std::swap(options[index], options[index+1]);
|
std::swap(options[index], options[index+1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<int> Deembedding::getAffectedPorts()
|
||||||
|
{
|
||||||
|
set<int> ret;
|
||||||
|
for(auto o : options) {
|
||||||
|
auto affected = o->getAffectedPorts();
|
||||||
|
ret.insert(affected.begin(), affected.end());
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
nlohmann::json Deembedding::toJSON()
|
nlohmann::json Deembedding::toJSON()
|
||||||
{
|
{
|
||||||
nlohmann::json list;
|
nlohmann::json list;
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "Traces/tracemodel.h"
|
#include "Traces/tracemodel.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
@ -20,11 +22,14 @@ public:
|
|||||||
~Deembedding(){}
|
~Deembedding(){}
|
||||||
|
|
||||||
void Deembed(VirtualDevice::VNAMeasurement &d);
|
void Deembed(VirtualDevice::VNAMeasurement &d);
|
||||||
void Deembed(Trace &S11, Trace &S12, Trace &S21, Trace &S22);
|
void Deembed(std::map<QString, Trace*> traceSet);
|
||||||
|
|
||||||
void removeOption(unsigned int index);
|
void removeOption(unsigned int index);
|
||||||
void addOption(DeembeddingOption* option);
|
void addOption(DeembeddingOption* option);
|
||||||
void swapOptions(unsigned int index);
|
void swapOptions(unsigned int index);
|
||||||
|
|
||||||
|
std::set<int> getAffectedPorts();
|
||||||
|
|
||||||
std::vector<DeembeddingOption*>& getOptions() {return options;}
|
std::vector<DeembeddingOption*>& getOptions() {return options;}
|
||||||
nlohmann::json toJSON() override;
|
nlohmann::json toJSON() override;
|
||||||
void fromJSON(nlohmann::json j) override;
|
void fromJSON(nlohmann::json j) override;
|
||||||
@ -36,7 +41,7 @@ signals:
|
|||||||
void allOptionsCleared();
|
void allOptionsCleared();
|
||||||
private:
|
private:
|
||||||
void measurementCompleted();
|
void measurementCompleted();
|
||||||
void startMeasurementDialog(bool S11, bool S12, bool S21, bool S22);
|
void startMeasurementDialog(DeembeddingOption *option);
|
||||||
std::vector<DeembeddingOption*> options;
|
std::vector<DeembeddingOption*> options;
|
||||||
DeembeddingOption *measuringOption;
|
DeembeddingOption *measuringOption;
|
||||||
TraceModel &tm;
|
TraceModel &tm;
|
||||||
|
@ -23,6 +23,7 @@ public:
|
|||||||
static DeembeddingOption *create(Type type);
|
static DeembeddingOption *create(Type type);
|
||||||
static QString getName(Type type);
|
static QString getName(Type type);
|
||||||
|
|
||||||
|
virtual std::set<int> getAffectedPorts() = 0;
|
||||||
virtual void transformDatapoint(VirtualDevice::VNAMeasurement &p) = 0;
|
virtual void transformDatapoint(VirtualDevice::VNAMeasurement &p) = 0;
|
||||||
virtual void edit(){}
|
virtual void edit(){}
|
||||||
virtual Type getType() = 0;
|
virtual Type getType() = 0;
|
||||||
@ -33,7 +34,7 @@ signals:
|
|||||||
// Deembedding option may selfdestruct if not applicable with current settings. It should emit this signal before deleting itself
|
// Deembedding option may selfdestruct if not applicable with current settings. It should emit this signal before deleting itself
|
||||||
void deleted(DeembeddingOption *option);
|
void deleted(DeembeddingOption *option);
|
||||||
|
|
||||||
void triggerMeasurement(bool S11 = true, bool S12 = true, bool S21 = true, bool S22 = true);
|
void triggerMeasurement();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEEMBEDDING_H
|
#endif // DEEMBEDDING_H
|
||||||
|
@ -15,6 +15,15 @@ ImpedanceRenormalization::ImpedanceRenormalization()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<int> ImpedanceRenormalization::getAffectedPorts()
|
||||||
|
{
|
||||||
|
set<int> ret;
|
||||||
|
for(int i=1;i<=VirtualDevice::getInfo(VirtualDevice::getConnected()).ports;i++) {
|
||||||
|
ret.insert(i);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void ImpedanceRenormalization::transformDatapoint(VirtualDevice::VNAMeasurement &p)
|
void ImpedanceRenormalization::transformDatapoint(VirtualDevice::VNAMeasurement &p)
|
||||||
{
|
{
|
||||||
std::map<QString, std::complex<double>> transformed;
|
std::map<QString, std::complex<double>> transformed;
|
||||||
|
@ -13,6 +13,7 @@ class ImpedanceRenormalization : public DeembeddingOption
|
|||||||
public:
|
public:
|
||||||
ImpedanceRenormalization();
|
ImpedanceRenormalization();
|
||||||
|
|
||||||
|
std::set<int> getAffectedPorts() override;
|
||||||
void transformDatapoint(VirtualDevice::VNAMeasurement &p) override;
|
void transformDatapoint(VirtualDevice::VNAMeasurement &p) override;
|
||||||
Type getType() override { return Type::ImpedanceRenormalization;}
|
Type getType() override { return Type::ImpedanceRenormalization;}
|
||||||
nlohmann::json toJSON() override;
|
nlohmann::json toJSON() override;
|
||||||
|
@ -7,13 +7,12 @@ 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, 2);
|
auto traceSelector = new SparamTraceSelector(model, deemb->getAffectedPorts());
|
||||||
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);
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=]() {
|
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=]() {
|
||||||
auto t = traceSelector->getTraces();
|
deemb->Deembed(traceSelector->getTraces());
|
||||||
deemb->Deembed(*t[0], *t[1], *t[2], *t[3]);
|
|
||||||
accept();
|
accept();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,11 @@ MatchingNetwork::MatchingNetwork()
|
|||||||
port = 1;
|
port = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<int> MatchingNetwork::getAffectedPorts()
|
||||||
|
{
|
||||||
|
return {port};
|
||||||
|
}
|
||||||
|
|
||||||
void MatchingNetwork::transformDatapoint(VirtualDevice::VNAMeasurement &p)
|
void MatchingNetwork::transformDatapoint(VirtualDevice::VNAMeasurement &p)
|
||||||
{
|
{
|
||||||
auto S = p.toSparam(1, 2);
|
auto S = p.toSparam(1, 2);
|
||||||
@ -106,12 +111,12 @@ void MatchingNetwork::edit()
|
|||||||
p1->setMinimumSize(portWidth, 151);
|
p1->setMinimumSize(portWidth, 151);
|
||||||
p1->setMaximumSize(portWidth, 151);
|
p1->setMaximumSize(portWidth, 151);
|
||||||
p1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
p1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
p1->setStyleSheet("image: url(:/icons/port1.png);");
|
p1->setStyleSheet("image: url(:/icons/port.png);");
|
||||||
auto DUT = new QWidget();
|
auto DUT = new QWidget();
|
||||||
DUT->setMinimumSize(DUTWidth, 151);
|
DUT->setMinimumSize(DUTWidth, 151);
|
||||||
DUT->setMaximumSize(DUTWidth, 151);
|
DUT->setMaximumSize(DUTWidth, 151);
|
||||||
DUT->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
DUT->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
DUT->setStyleSheet("image: url(:/icons/DUT.png);");
|
DUT->setStyleSheet("image: url(:/icons/DUT_onePort.png);");
|
||||||
|
|
||||||
layout->addWidget(p1);
|
layout->addWidget(p1);
|
||||||
for(auto w : network) {
|
for(auto w : network) {
|
||||||
|
@ -64,6 +64,7 @@ public:
|
|||||||
|
|
||||||
// DeembeddingOption interface
|
// DeembeddingOption interface
|
||||||
public:
|
public:
|
||||||
|
std::set<int> getAffectedPorts() override;
|
||||||
void transformDatapoint(VirtualDevice::VNAMeasurement &p) override;
|
void transformDatapoint(VirtualDevice::VNAMeasurement &p) override;
|
||||||
void edit() override;
|
void edit() override;
|
||||||
Type getType() override {return Type::MatchingNetwork;}
|
Type getType() override {return Type::MatchingNetwork;}
|
||||||
|
@ -24,6 +24,11 @@ PortExtension::PortExtension()
|
|||||||
kit = nullptr;
|
kit = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<int> PortExtension::getAffectedPorts()
|
||||||
|
{
|
||||||
|
return {port};
|
||||||
|
}
|
||||||
|
|
||||||
void PortExtension::transformDatapoint(VirtualDevice::VNAMeasurement &d)
|
void PortExtension::transformDatapoint(VirtualDevice::VNAMeasurement &d)
|
||||||
{
|
{
|
||||||
auto phase = -2 * M_PI * ext.delay * d.frequency;
|
auto phase = -2 * M_PI * ext.delay * d.frequency;
|
||||||
@ -72,6 +77,8 @@ void PortExtension::edit()
|
|||||||
ui->DCloss->setValue(ext.DCloss);
|
ui->DCloss->setValue(ext.DCloss);
|
||||||
ui->Loss->setValue(ext.loss);
|
ui->Loss->setValue(ext.loss);
|
||||||
ui->Frequency->setValue(ext.frequency);
|
ui->Frequency->setValue(ext.frequency);
|
||||||
|
ui->port->setValue(port);
|
||||||
|
ui->port->setMaximum(VirtualDevice::getInfo(VirtualDevice::getConnected()).ports);
|
||||||
if(!kit) {
|
if(!kit) {
|
||||||
ui->calkit->setEnabled(false);
|
ui->calkit->setEnabled(false);
|
||||||
}
|
}
|
||||||
@ -97,6 +104,9 @@ void PortExtension::edit()
|
|||||||
ui->Time->setValueQuiet(ui->Distance->value() / (newval * c));
|
ui->Time->setValueQuiet(ui->Distance->value() / (newval * c));
|
||||||
updateValuesFromUI();
|
updateValuesFromUI();
|
||||||
});
|
});
|
||||||
|
connect(ui->port, qOverload<int>(&QSpinBox::valueChanged), [=](){
|
||||||
|
port = ui->port->value();
|
||||||
|
});
|
||||||
connect(ui->DCloss, &SIUnitEdit::valueChanged, updateValuesFromUI);
|
connect(ui->DCloss, &SIUnitEdit::valueChanged, updateValuesFromUI);
|
||||||
connect(ui->Loss, &SIUnitEdit::valueChanged, updateValuesFromUI);
|
connect(ui->Loss, &SIUnitEdit::valueChanged, updateValuesFromUI);
|
||||||
connect(ui->Frequency, &SIUnitEdit::valueChanged, updateValuesFromUI);
|
connect(ui->Frequency, &SIUnitEdit::valueChanged, updateValuesFromUI);
|
||||||
|
@ -18,6 +18,7 @@ class PortExtension : public DeembeddingOption
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
PortExtension();
|
PortExtension();
|
||||||
|
std::set<int> getAffectedPorts() override;
|
||||||
void transformDatapoint(VirtualDevice::VNAMeasurement& d) override;
|
void transformDatapoint(VirtualDevice::VNAMeasurement& d) override;
|
||||||
void setCalkit(Calkit *kit);
|
void setCalkit(Calkit *kit);
|
||||||
Type getType() override {return Type::PortExtension;}
|
Type getType() override {return Type::PortExtension;}
|
||||||
|
@ -17,6 +17,11 @@ TwoThru::TwoThru()
|
|||||||
port2 = 2;
|
port2 = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<int> TwoThru::getAffectedPorts()
|
||||||
|
{
|
||||||
|
return {port1, port2};
|
||||||
|
}
|
||||||
|
|
||||||
void TwoThru::transformDatapoint(VirtualDevice::VNAMeasurement &p)
|
void TwoThru::transformDatapoint(VirtualDevice::VNAMeasurement &p)
|
||||||
{
|
{
|
||||||
// correct measurement
|
// correct measurement
|
||||||
|
@ -16,6 +16,7 @@ class TwoThru : public DeembeddingOption
|
|||||||
public:
|
public:
|
||||||
TwoThru();
|
TwoThru();
|
||||||
|
|
||||||
|
std::set<int> getAffectedPorts() override;
|
||||||
virtual void transformDatapoint(VirtualDevice::VNAMeasurement& p) override;
|
virtual void transformDatapoint(VirtualDevice::VNAMeasurement& p) override;
|
||||||
virtual void edit() override;
|
virtual void edit() override;
|
||||||
virtual Type getType() override {return DeembeddingOption::Type::TwoThru;}
|
virtual Type getType() override {return DeembeddingOption::Type::TwoThru;}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<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>
|
<string>You imported a touchstone file, do you want to apply the currently active calibration or de-embed the data?</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -55,6 +55,7 @@ void TraceWidgetVNA::importDialog()
|
|||||||
if (!filename.isEmpty()) {
|
if (!filename.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
std::vector<Trace*> traces;
|
std::vector<Trace*> traces;
|
||||||
|
int touchstonePorts = 0;
|
||||||
QString prefix = QString();
|
QString prefix = QString();
|
||||||
if(filename.endsWith(".csv")) {
|
if(filename.endsWith(".csv")) {
|
||||||
auto csv = CSV::fromFile(filename);
|
auto csv = CSV::fromFile(filename);
|
||||||
@ -63,6 +64,7 @@ void TraceWidgetVNA::importDialog()
|
|||||||
// must be a touchstone file
|
// must be a touchstone file
|
||||||
auto t = Touchstone::fromFile(filename.toStdString());
|
auto t = Touchstone::fromFile(filename.toStdString());
|
||||||
traces = Trace::createFromTouchstone(t);
|
traces = Trace::createFromTouchstone(t);
|
||||||
|
touchstonePorts = t.ports();
|
||||||
}
|
}
|
||||||
// contruct prefix from filename
|
// contruct prefix from filename
|
||||||
prefix = filename;
|
prefix = filename;
|
||||||
@ -78,10 +80,9 @@ void TraceWidgetVNA::importDialog()
|
|||||||
if(AppWindow::showGUI()) {
|
if(AppWindow::showGUI()) {
|
||||||
i->show();
|
i->show();
|
||||||
}
|
}
|
||||||
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() == touchstonePorts*touchstonePorts) {
|
||||||
// all traces imported, can calculate calibration/de-embedding
|
// all traces imported, can calculate calibration/de-embedding
|
||||||
bool calAvailable = cal.getNumPoints() > 0;
|
bool calAvailable = cal.getNumPoints() > 0;
|
||||||
bool deembedAvailable = deembed.getOptions().size() > 0;
|
bool deembedAvailable = deembed.getOptions().size() > 0;
|
||||||
@ -106,16 +107,24 @@ void TraceWidgetVNA::importDialog()
|
|||||||
if(AppWindow::showGUI()) {
|
if(AppWindow::showGUI()) {
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
}
|
}
|
||||||
|
// assemble trace set
|
||||||
|
std::map<QString, Trace*> set;
|
||||||
|
for(int i=1;i<=touchstonePorts;i++) {
|
||||||
|
for(int j=1;j<=touchstonePorts;j++) {
|
||||||
|
QString name = "S"+QString::number(i)+QString::number(j);
|
||||||
|
int index = (i-1)*touchstonePorts+(j-1);
|
||||||
|
set[name] = traces[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
if(applyCal) {
|
if(applyCal) {
|
||||||
// cal.correctTraces(*traces[0], *traces[1], *traces[2], *traces[3]); // TODO
|
cal.correctTraces(set);
|
||||||
}
|
}
|
||||||
if(applyDeembed) {
|
if(applyDeembed) {
|
||||||
deembed.Deembed(*traces[0], *traces[1], *traces[2], *traces[3]);
|
deembed.Deembed(set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} catch(const std::exception& e) {
|
} catch(const std::exception& e) {
|
||||||
InformationBox::ShowError("Failed to import file", QString("Attempt to import file ended with error: \"") + e.what()+"\"");
|
InformationBox::ShowError("Failed to import file", QString("Attempt to import file ended with error: \"") + e.what()+"\"");
|
||||||
}
|
}
|
||||||
|
@ -573,8 +573,23 @@ void AppWindow::SetupSCPI()
|
|||||||
if(!vdevice) {
|
if(!vdevice) {
|
||||||
return QString("0/0/0");
|
return QString("0/0/0");
|
||||||
} else if(vdevice->isCompoundDevice()) {
|
} else if(vdevice->isCompoundDevice()) {
|
||||||
// TODO
|
// show highest temperature of all devices
|
||||||
return QString();
|
int maxTempSource = 0;
|
||||||
|
int maxTempLO = 0;
|
||||||
|
int maxTempMCU = 0;
|
||||||
|
for(auto dev : vdevice->getDevices()) {
|
||||||
|
auto status = dev->StatusV1();
|
||||||
|
if(status.temp_source > maxTempSource) {
|
||||||
|
maxTempSource = status.temp_source;
|
||||||
|
}
|
||||||
|
if(status.temp_LO1 > maxTempLO) {
|
||||||
|
maxTempLO = status.temp_LO1;
|
||||||
|
}
|
||||||
|
if(status.temp_MCU > maxTempMCU) {
|
||||||
|
maxTempMCU = status.temp_MCU;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QString::number(maxTempSource)+"/"+QString::number(maxTempLO)+"/"+QString::number(maxTempMCU);
|
||||||
} else {
|
} else {
|
||||||
auto dev = vdevice->getDevice();
|
auto dev = vdevice->getDevice();
|
||||||
return QString::number(dev->StatusV1().temp_source)+"/"+QString::number(dev->StatusV1().temp_LO1)+"/"+QString::number(dev->StatusV1().temp_MCU);
|
return QString::number(dev->StatusV1().temp_source)+"/"+QString::number(dev->StatusV1().temp_LO1)+"/"+QString::number(dev->StatusV1().temp_MCU);
|
||||||
|
@ -67,5 +67,7 @@
|
|||||||
<file>icons/compound_V1_Ref_Middle.png</file>
|
<file>icons/compound_V1_Ref_Middle.png</file>
|
||||||
<file>icons/compound_V1_Ref_Right.png</file>
|
<file>icons/compound_V1_Ref_Right.png</file>
|
||||||
<file>icons/compound_V1_USB.png</file>
|
<file>icons/compound_V1_USB.png</file>
|
||||||
|
<file>icons/DUT_onePort.png</file>
|
||||||
|
<file>icons/port.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 275 B |
BIN
Software/PC_Application/icons/DUT_onePort.png
Normal file
BIN
Software/PC_Application/icons/DUT_onePort.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 909 B |
BIN
Software/PC_Application/icons/port.png
Normal file
BIN
Software/PC_Application/icons/port.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
Loading…
Reference in New Issue
Block a user