keep original trace data when de-embedding, toggle de-embedding view for individual traces
This commit is contained in:
parent
b67275831b
commit
89c9f20d16
@ -91,11 +91,11 @@ public:
|
|||||||
};
|
};
|
||||||
static TypeInfo getInfo(Type type);
|
static TypeInfo getInfo(Type type);
|
||||||
|
|
||||||
Data getSample(unsigned int index);
|
virtual Data getSample(unsigned int index);
|
||||||
Data getInterpolatedSample(double x);
|
virtual Data getInterpolatedSample(double x);
|
||||||
double getStepResponse(unsigned int index);
|
double getStepResponse(unsigned int index);
|
||||||
double getInterpolatedStepResponse(double x);
|
double getInterpolatedStepResponse(double x);
|
||||||
unsigned int numSamples();
|
virtual unsigned int numSamples();
|
||||||
|
|
||||||
static QString dataTypeToString(DataType type);
|
static QString dataTypeToString(DataType type);
|
||||||
static DataType dataTypeFromString(QString s);
|
static DataType dataTypeFromString(QString s);
|
||||||
|
@ -74,6 +74,7 @@ void Trace::clear(bool force) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data.clear();
|
data.clear();
|
||||||
|
clearDeembedding();
|
||||||
settings.valid = false;
|
settings.valid = false;
|
||||||
warning("No data");
|
warning("No data");
|
||||||
emit cleared(this);
|
emit cleared(this);
|
||||||
@ -149,6 +150,39 @@ void Trace::addData(const Trace::Data &d, const VirtualDevice::SASettings &s, in
|
|||||||
addData(d, domain, 50.0, index);
|
addData(d, domain, 50.0, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Trace::addDeembeddingData(const Trace::Data &d, int index)
|
||||||
|
{
|
||||||
|
if(index >= 0) {
|
||||||
|
// index position specified
|
||||||
|
if(deembeddingData.size() <= (unsigned int) index) {
|
||||||
|
deembeddingData.resize(index + 1);
|
||||||
|
}
|
||||||
|
deembeddingData[index] = d;
|
||||||
|
} else {
|
||||||
|
// no index given, determine position by X-coordinate
|
||||||
|
|
||||||
|
// add or replace data in vector while keeping it sorted with increasing frequency
|
||||||
|
auto lower = lower_bound(deembeddingData.begin(), deembeddingData.end(), d, [](const Data &lhs, const Data &rhs) -> bool {
|
||||||
|
return lhs.x < rhs.x;
|
||||||
|
});
|
||||||
|
// calculate index now because inserting a sample into data might lead to reallocation -> arithmetic on lower not valid anymore
|
||||||
|
index = lower - deembeddingData.begin();
|
||||||
|
if(lower == deembeddingData.end()) {
|
||||||
|
// highest frequency yet, add to vector
|
||||||
|
deembeddingData.push_back(d);
|
||||||
|
} else if(lower->x == d.x) {
|
||||||
|
*lower = d;
|
||||||
|
} else {
|
||||||
|
// insert at this position
|
||||||
|
deembeddingData.insert(lower, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(deembeddingActive) {
|
||||||
|
emit outputSamplesChanged(index, index + 1);
|
||||||
|
}
|
||||||
|
emit deembeddingChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void Trace::setName(QString name) {
|
void Trace::setName(QString name) {
|
||||||
_name = name;
|
_name = name;
|
||||||
emit nameChanged();
|
emit nameChanged();
|
||||||
@ -265,11 +299,15 @@ QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
|
|||||||
return lastTraceName;
|
return lastTraceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Trace::fillFromDatapoints(std::map<QString, Trace *> traceSet, const std::vector<VirtualDevice::VNAMeasurement> &data)
|
void Trace::fillFromDatapoints(std::map<QString, Trace *> traceSet, const std::vector<VirtualDevice::VNAMeasurement> &data, bool deembedded)
|
||||||
{
|
{
|
||||||
// remove all previous points
|
// remove all previous points
|
||||||
for(auto m : traceSet) {
|
for(auto m : traceSet) {
|
||||||
m.second->clear();
|
if(!deembedded) {
|
||||||
|
m.second->clear();
|
||||||
|
} else {
|
||||||
|
m.second->clearDeembedding();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// add new points to traces
|
// add new points to traces
|
||||||
for(auto d : data) {
|
for(auto d : data) {
|
||||||
@ -279,7 +317,11 @@ void Trace::fillFromDatapoints(std::map<QString, Trace *> traceSet, const std::v
|
|||||||
td.y = m.second;
|
td.y = m.second;
|
||||||
QString measurement = m.first;
|
QString measurement = m.first;
|
||||||
if(traceSet.count(measurement)) {
|
if(traceSet.count(measurement)) {
|
||||||
traceSet[measurement]->addData(td, DataType::Frequency);
|
if(!deembedded) {
|
||||||
|
traceSet[measurement]->addData(td, DataType::Frequency);
|
||||||
|
} else {
|
||||||
|
traceSet[measurement]->addDeembeddingData(td);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -743,6 +785,17 @@ nlohmann::json Trace::toJSON()
|
|||||||
j["data"] = jdata;
|
j["data"] = jdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
j["deembeddingActive"] = deembeddingActive;
|
||||||
|
nlohmann::json jdedata;
|
||||||
|
for(const auto &d : deembeddingData) {
|
||||||
|
nlohmann::json jpoint;
|
||||||
|
jpoint["x"] = d.x;
|
||||||
|
jpoint["real"] = d.y.real();
|
||||||
|
jpoint["imag"] = d.y.imag();
|
||||||
|
jdedata.push_back(jpoint);
|
||||||
|
}
|
||||||
|
j["deembeddingData"] = jdedata;
|
||||||
|
|
||||||
nlohmann::json mathList;
|
nlohmann::json mathList;
|
||||||
for(auto m : mathOps) {
|
for(auto m : mathOps) {
|
||||||
if(m.math->getType() == Type::Last) {
|
if(m.math->getType() == Type::Last) {
|
||||||
@ -759,6 +812,7 @@ nlohmann::json Trace::toJSON()
|
|||||||
j["math"] = mathList;
|
j["math"] = mathList;
|
||||||
j["math_enabled"] = mathEnabled();
|
j["math_enabled"] = mathEnabled();
|
||||||
|
|
||||||
|
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -785,6 +839,18 @@ void Trace::fromJSON(nlohmann::json j)
|
|||||||
data.push_back(d);
|
data.push_back(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(j.contains("deembeddingData")) {
|
||||||
|
// Deembedded data is contained in the json, load now
|
||||||
|
clearDeembedding();
|
||||||
|
for(auto jpoint : j["deembeddingData"]) {
|
||||||
|
Data d;
|
||||||
|
d.x = jpoint.value("x", 0.0);
|
||||||
|
d.y = complex<double>(jpoint.value("real", 0.0), jpoint.value("imag", 0.0));
|
||||||
|
deembeddingData.push_back(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deembeddingActive = j.value("deembeddingActive", false);
|
||||||
|
|
||||||
if(type == "Live") {
|
if(type == "Live") {
|
||||||
if(j.contains("parameter")) {
|
if(j.contains("parameter")) {
|
||||||
if(j["parameter"].type() == nlohmann::json::value_t::string) {
|
if(j["parameter"].type() == nlohmann::json::value_t::string) {
|
||||||
@ -1226,6 +1292,36 @@ unsigned int Trace::size() const
|
|||||||
return lastMath->numSamples();
|
return lastMath->numSamples();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Trace::isDeembeddingActive()
|
||||||
|
{
|
||||||
|
return deembeddingActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Trace::deembeddingAvailable()
|
||||||
|
{
|
||||||
|
return deembeddingData.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Trace::setDeembeddingActive(bool active)
|
||||||
|
{
|
||||||
|
deembeddingActive = active;
|
||||||
|
if(deembeddingAvailable()) {
|
||||||
|
if(active) {
|
||||||
|
emit outputSamplesChanged(0, deembeddingData.size());
|
||||||
|
} else {
|
||||||
|
emit outputSamplesChanged(0, data.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit deembeddingChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Trace::clearDeembedding()
|
||||||
|
{
|
||||||
|
setDeembeddingActive(false);
|
||||||
|
deembeddingData.clear();
|
||||||
|
deembeddingChanged();
|
||||||
|
}
|
||||||
|
|
||||||
double Trace::minX()
|
double Trace::minX()
|
||||||
{
|
{
|
||||||
if(lastMath->numSamples() > 0) {
|
if(lastMath->numSamples() > 0) {
|
||||||
@ -1331,6 +1427,60 @@ Trace::Data Trace::sample(unsigned int index, bool getStepResponse) const
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Trace::Data Trace::getSample(unsigned int index)
|
||||||
|
{
|
||||||
|
if(deembeddingActive && deembeddingAvailable()) {
|
||||||
|
if(index < deembeddingData.size()) {
|
||||||
|
return deembeddingData[index];
|
||||||
|
} else {
|
||||||
|
TraceMath::Data d;
|
||||||
|
d.x = 0;
|
||||||
|
d.y = 0;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return TraceMath::getSample(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Trace::Data Trace::getInterpolatedSample(double x)
|
||||||
|
{
|
||||||
|
if(deembeddingActive && deembeddingAvailable()) {
|
||||||
|
Data ret;
|
||||||
|
if(deembeddingData.size() == 0 || x < deembeddingData.front().x || x > deembeddingData.back().x) {
|
||||||
|
ret.y = std::numeric_limits<std::complex<double>>::quiet_NaN();
|
||||||
|
ret.x = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
} else {
|
||||||
|
auto it = lower_bound(deembeddingData.begin(), deembeddingData.end(), x, [](const Data &lhs, const double x) -> bool {
|
||||||
|
return lhs.x < x;
|
||||||
|
});
|
||||||
|
if(it->x == x) {
|
||||||
|
ret = *it;
|
||||||
|
} else {
|
||||||
|
// no exact match, needs to interpolate
|
||||||
|
auto high = *it;
|
||||||
|
it--;
|
||||||
|
auto low = *it;
|
||||||
|
double alpha = (x - low.x) / (high.x - low.x);
|
||||||
|
ret.y = low.y * (1 - alpha) + high.y * alpha;
|
||||||
|
ret.x = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
return TraceMath::getInterpolatedSample(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Trace::numSamples()
|
||||||
|
{
|
||||||
|
if(deembeddingActive && deembeddingAvailable()) {
|
||||||
|
return deembeddingData.size();
|
||||||
|
} else {
|
||||||
|
return TraceMath::numSamples();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double Trace::getUnwrappedPhase(unsigned int index)
|
double Trace::getUnwrappedPhase(unsigned int index)
|
||||||
{
|
{
|
||||||
if(index >= size()) {
|
if(index >= size()) {
|
||||||
|
@ -45,11 +45,12 @@ public:
|
|||||||
void clear(bool force = false);
|
void clear(bool force = false);
|
||||||
void addData(const Data& d, DataType domain, double reference_impedance = 50.0, int index = -1);
|
void addData(const Data& d, DataType domain, double reference_impedance = 50.0, int index = -1);
|
||||||
void addData(const Data& d, const VirtualDevice::SASettings &s, int index = -1);
|
void addData(const Data& d, const VirtualDevice::SASettings &s, int index = -1);
|
||||||
|
void addDeembeddingData(const Data& d, int index = -1);
|
||||||
void setName(QString name);
|
void setName(QString name);
|
||||||
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(std::map<QString, Trace*> traceSet, const std::vector<VirtualDevice::VNAMeasurement> &data);
|
static void fillFromDatapoints(std::map<QString, Trace*> traceSet, const std::vector<VirtualDevice::VNAMeasurement> &data, bool deembedded = false);
|
||||||
void fromLivedata(LivedataType type, QString param);
|
void fromLivedata(LivedataType type, QString param);
|
||||||
void fromMath();
|
void fromMath();
|
||||||
QString name() { return _name; }
|
QString name() { return _name; }
|
||||||
@ -65,6 +66,12 @@ public:
|
|||||||
LivedataType liveType() { return _liveType; }
|
LivedataType liveType() { return _liveType; }
|
||||||
TraceMath::DataType outputType() const { return lastMath->getDataType(); }
|
TraceMath::DataType outputType() const { return lastMath->getDataType(); }
|
||||||
unsigned int size() const;
|
unsigned int size() const;
|
||||||
|
|
||||||
|
bool isDeembeddingActive();
|
||||||
|
bool deembeddingAvailable();
|
||||||
|
void setDeembeddingActive(bool active);
|
||||||
|
void clearDeembedding();
|
||||||
|
|
||||||
double minX();
|
double minX();
|
||||||
double maxX();
|
double maxX();
|
||||||
double findExtremum(bool max, double xmin = std::numeric_limits<double>::lowest(), double xmax = std::numeric_limits<double>::max());
|
double findExtremum(bool max, double xmin = std::numeric_limits<double>::lowest(), double xmax = std::numeric_limits<double>::max());
|
||||||
@ -82,6 +89,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
Data sample(unsigned int index, bool getStepResponse = false) const;
|
Data sample(unsigned int index, bool getStepResponse = false) const;
|
||||||
|
|
||||||
|
virtual Data getSample(unsigned int index) override;
|
||||||
|
virtual Data getInterpolatedSample(double x) override;
|
||||||
|
virtual unsigned int numSamples() override;
|
||||||
|
|
||||||
double getUnwrappedPhase(unsigned int index);
|
double getUnwrappedPhase(unsigned int index);
|
||||||
// returns a (possibly interpolated sample) at a specified frequency/time/power
|
// returns a (possibly interpolated sample) at a specified frequency/time/power
|
||||||
Data interpolatedSample(double x);
|
Data interpolatedSample(double x);
|
||||||
@ -190,6 +202,7 @@ signals:
|
|||||||
void dataChanged(unsigned int begin, unsigned int end);
|
void dataChanged(unsigned int begin, unsigned int end);
|
||||||
void nameChanged();
|
void nameChanged();
|
||||||
void pauseChanged();
|
void pauseChanged();
|
||||||
|
void deembeddingChanged();
|
||||||
void colorChanged(Trace *t);
|
void colorChanged(Trace *t);
|
||||||
void markerAdded(Marker *m);
|
void markerAdded(Marker *m);
|
||||||
void markerRemoved(Marker *m);
|
void markerRemoved(Marker *m);
|
||||||
@ -266,6 +279,10 @@ private:
|
|||||||
bool valid;
|
bool valid;
|
||||||
} settings;
|
} settings;
|
||||||
|
|
||||||
|
// de-embedding variables
|
||||||
|
std::vector<Data> deembeddingData;
|
||||||
|
bool deembeddingActive;
|
||||||
|
|
||||||
std::vector<MathInfo> mathOps;
|
std::vector<MathInfo> mathOps;
|
||||||
TraceMath *lastMath;
|
TraceMath *lastMath;
|
||||||
std::vector<double> unwrappedPhase;
|
std::vector<double> unwrappedPhase;
|
||||||
|
@ -32,6 +32,9 @@ void TraceModel::addTrace(Trace *t)
|
|||||||
connect(t, &Trace::pauseChanged, [=](){
|
connect(t, &Trace::pauseChanged, [=](){
|
||||||
emit dataChanged(createIndex(0, 0), createIndex(traces.size() - 1, ColIndexLast - 1));
|
emit dataChanged(createIndex(0, 0), createIndex(traces.size() - 1, ColIndexLast - 1));
|
||||||
});
|
});
|
||||||
|
connect(t, &Trace::deembeddingChanged, [=](){
|
||||||
|
emit dataChanged(createIndex(0, 0), createIndex(traces.size() - 1, ColIndexLast - 1));
|
||||||
|
});
|
||||||
traces.push_back(t);
|
traces.push_back(t);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
t->setModel(this);
|
t->setModel(this);
|
||||||
@ -106,6 +109,18 @@ void TraceModel::toggleMath(unsigned int index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TraceModel::toggleDeembedding(unsigned int index)
|
||||||
|
{
|
||||||
|
if (index >= traces.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto trace = traces[index];
|
||||||
|
if(trace->deembeddingAvailable()) {
|
||||||
|
trace->setDeembeddingActive(!trace->isDeembeddingActive());
|
||||||
|
emit dataChanged(createIndex(index, ColIndexDeembedding), createIndex(index, ColIndexDeembedding));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int TraceModel::rowCount(const QModelIndex &) const
|
int TraceModel::rowCount(const QModelIndex &) const
|
||||||
{
|
{
|
||||||
return traces.size();
|
return traces.size();
|
||||||
@ -133,6 +148,8 @@ QVariant TraceModel::data(const QModelIndex &index, int role) const
|
|||||||
} else {
|
} else {
|
||||||
return QIcon(":/icons/invisible.svg");
|
return QIcon(":/icons/invisible.svg");
|
||||||
}
|
}
|
||||||
|
} else if(role == Qt::ToolTipRole){
|
||||||
|
return "Toggle Visibility";
|
||||||
} else {
|
} else {
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -144,6 +161,21 @@ QVariant TraceModel::data(const QModelIndex &index, int role) const
|
|||||||
} else {
|
} else {
|
||||||
return QIcon(":/icons/play.svg");
|
return QIcon(":/icons/play.svg");
|
||||||
}
|
}
|
||||||
|
} else if(role == Qt::ToolTipRole && trace->canBePaused()){
|
||||||
|
return "Toggle Play/Pause";
|
||||||
|
} else {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ColIndexDeembedding:
|
||||||
|
if (role == Qt::DecorationRole && trace->deembeddingAvailable()) {
|
||||||
|
if(trace->isDeembeddingActive()) {
|
||||||
|
return QIcon(":icons/deembedding_enabled.svg");
|
||||||
|
} else {
|
||||||
|
return QIcon(":icons/deembedding_disabled.svg");
|
||||||
|
}
|
||||||
|
} else if(role == Qt::ToolTipRole && trace->deembeddingAvailable()){
|
||||||
|
return "Toggle De-embedding";
|
||||||
} else {
|
} else {
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -155,6 +187,10 @@ QVariant TraceModel::data(const QModelIndex &index, int role) const
|
|||||||
} else {
|
} else {
|
||||||
return QIcon(":icons/math_disabled");
|
return QIcon(":icons/math_disabled");
|
||||||
}
|
}
|
||||||
|
} else if(role == Qt::ToolTipRole && trace->hasMathOperations()){
|
||||||
|
return "Toggle Math Operations";
|
||||||
|
} else {
|
||||||
|
return QVariant();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ColIndexName:
|
case ColIndexName:
|
||||||
@ -175,6 +211,17 @@ std::vector<Trace *> TraceModel::getTraces() const
|
|||||||
return traces;
|
return traces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Trace *> TraceModel::getLiveTraces() const
|
||||||
|
{
|
||||||
|
std::vector<Trace*> ret;
|
||||||
|
for(auto t : traces) {
|
||||||
|
if(t->getSource() == Trace::Source::Live) {
|
||||||
|
ret.push_back(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool TraceModel::PortExcitationRequired(int port)
|
bool TraceModel::PortExcitationRequired(int port)
|
||||||
{
|
{
|
||||||
port++;
|
port++;
|
||||||
@ -233,7 +280,7 @@ void TraceModel::clearLiveData()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceModel::addVNAData(const VirtualDevice::VNAMeasurement& d, TraceMath::DataType datatype)
|
void TraceModel::addVNAData(const VirtualDevice::VNAMeasurement& d, TraceMath::DataType datatype, bool deembedded)
|
||||||
{
|
{
|
||||||
source = DataSource::VNA;
|
source = DataSource::VNA;
|
||||||
lastReceivedData = QDateTime::currentDateTimeUtc();
|
lastReceivedData = QDateTime::currentDateTimeUtc();
|
||||||
@ -263,7 +310,11 @@ void TraceModel::addVNAData(const VirtualDevice::VNAMeasurement& d, TraceMath::D
|
|||||||
// parameter not included in data, skip
|
// parameter not included in data, skip
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
t->addData(td, datatype, d.Z0, index);
|
if(!deembedded) {
|
||||||
|
t->addData(td, datatype, d.Z0, index);
|
||||||
|
} else {
|
||||||
|
t->addDeembeddingData(td, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,9 @@ public:
|
|||||||
enum {
|
enum {
|
||||||
ColIndexVisible = 0,
|
ColIndexVisible = 0,
|
||||||
ColIndexPlayPause = 1,
|
ColIndexPlayPause = 1,
|
||||||
ColIndexMath = 2,
|
ColIndexDeembedding = 2,
|
||||||
ColIndexName = 3,
|
ColIndexMath = 3,
|
||||||
|
ColIndexName = 4,
|
||||||
ColIndexLast,
|
ColIndexLast,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -39,12 +40,14 @@ public:
|
|||||||
void toggleVisibility(unsigned int index);
|
void toggleVisibility(unsigned int index);
|
||||||
void togglePause(unsigned int index);
|
void togglePause(unsigned int index);
|
||||||
void toggleMath(unsigned int index);
|
void toggleMath(unsigned int index);
|
||||||
|
void toggleDeembedding(unsigned int index);
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
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() const;
|
std::vector<Trace*> getTraces() const;
|
||||||
|
std::vector<Trace*> getLiveTraces() const;
|
||||||
|
|
||||||
bool PortExcitationRequired(int port);
|
bool PortExcitationRequired(int port);
|
||||||
|
|
||||||
@ -68,7 +71,7 @@ signals:
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void clearLiveData();
|
void clearLiveData();
|
||||||
void addVNAData(const VirtualDevice::VNAMeasurement& d, TraceMath::DataType datatype);
|
void addVNAData(const VirtualDevice::VNAMeasurement& d, TraceMath::DataType datatype, bool deembedded);
|
||||||
void addSAData(const VirtualDevice::SAMeasurement &d, const VirtualDevice::SASettings &settings);
|
void addSAData(const VirtualDevice::SAMeasurement &d, const VirtualDevice::SASettings &settings);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -140,6 +140,8 @@ void TraceWidget::on_view_clicked(const QModelIndex &index)
|
|||||||
case TraceModel::ColIndexPlayPause:
|
case TraceModel::ColIndexPlayPause:
|
||||||
model.togglePause(index.row());
|
model.togglePause(index.row());
|
||||||
break;
|
break;
|
||||||
|
case TraceModel::ColIndexDeembedding:
|
||||||
|
model.toggleDeembedding(index.row());
|
||||||
case TraceModel::ColIndexMath:
|
case TraceModel::ColIndexMath:
|
||||||
model.toggleMath(index.row());
|
model.toggleMath(index.row());
|
||||||
break;
|
break;
|
||||||
|
@ -124,7 +124,10 @@ void Deembedding::Deembed(std::map<QString, Trace *> traceSet)
|
|||||||
for(auto &p : points) {
|
for(auto &p : points) {
|
||||||
Deembed(p);
|
Deembed(p);
|
||||||
}
|
}
|
||||||
Trace::fillFromDatapoints(traceSet, points);
|
Trace::fillFromDatapoints(traceSet, points, true);
|
||||||
|
for(auto t : traceSet) {
|
||||||
|
t.second->setDeembeddingActive(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "ui_manualdeembeddingdialog.h"
|
#include "ui_manualdeembeddingdialog.h"
|
||||||
#include "Traces/sparamtraceselector.h"
|
#include "Traces/sparamtraceselector.h"
|
||||||
|
#include "CustomWidgets/informationbox.h"
|
||||||
|
|
||||||
ManualDeembeddingDialog::ManualDeembeddingDialog(const TraceModel &model, Deembedding *deemb) :
|
ManualDeembeddingDialog::ManualDeembeddingDialog(const TraceModel &model, Deembedding *deemb) :
|
||||||
ui(new Ui::ManualDeembeddingDialog)
|
ui(new Ui::ManualDeembeddingDialog)
|
||||||
@ -12,6 +13,22 @@ ManualDeembeddingDialog::ManualDeembeddingDialog(const TraceModel &model, Deembe
|
|||||||
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 traces = traceSelector->getTraces();
|
||||||
|
bool clearDeembedding = false;
|
||||||
|
for(auto t : traces) {
|
||||||
|
if(t.second->deembeddingAvailable()) {
|
||||||
|
clearDeembedding = InformationBox::AskQuestion("Clear previous de-embedding data?", "At least one of the selected traces "
|
||||||
|
"has already been de-embedded. Do you want to clear the old de-embedding data before applying the new de-embedding?", true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(clearDeembedding) {
|
||||||
|
for(auto t : traces) {
|
||||||
|
if(t.second->deembeddingAvailable()) {
|
||||||
|
t.second->clearDeembedding();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
deemb->Deembed(traceSelector->getTraces());
|
deemb->Deembed(traceSelector->getTraces());
|
||||||
accept();
|
accept();
|
||||||
});
|
});
|
||||||
|
@ -850,10 +850,6 @@ void VNA::NewDatapoint(VirtualDevice::VNAMeasurement m)
|
|||||||
|
|
||||||
cal.correctMeasurement(m_avg);
|
cal.correctMeasurement(m_avg);
|
||||||
|
|
||||||
if(deembedding_active) {
|
|
||||||
deembedding.Deembed(m_avg);
|
|
||||||
}
|
|
||||||
|
|
||||||
TraceMath::DataType type;
|
TraceMath::DataType type;
|
||||||
if(settings.zerospan) {
|
if(settings.zerospan) {
|
||||||
type = TraceMath::DataType::TimeZeroSpan;
|
type = TraceMath::DataType::TimeZeroSpan;
|
||||||
@ -877,7 +873,11 @@ void VNA::NewDatapoint(VirtualDevice::VNAMeasurement m)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
traceModel.addVNAData(m_avg, type);
|
traceModel.addVNAData(m_avg, type, false);
|
||||||
|
if(deembedding_active) {
|
||||||
|
deembedding.Deembed(m_avg);
|
||||||
|
traceModel.addVNAData(m_avg, type, true);
|
||||||
|
}
|
||||||
emit dataChanged();
|
emit dataChanged();
|
||||||
if(m_avg.pointNum == settings.npoints - 1) {
|
if(m_avg.pointNum == settings.npoints - 1) {
|
||||||
UpdateAverageCount();
|
UpdateAverageCount();
|
||||||
@ -1579,6 +1579,14 @@ void VNA::EnableDeembedding(bool enable)
|
|||||||
enableDeembeddingAction->blockSignals(true);
|
enableDeembeddingAction->blockSignals(true);
|
||||||
enableDeembeddingAction->setChecked(enable);
|
enableDeembeddingAction->setChecked(enable);
|
||||||
enableDeembeddingAction->blockSignals(false);
|
enableDeembeddingAction->blockSignals(false);
|
||||||
|
for(auto t : traceModel.getLiveTraces()) {
|
||||||
|
if(enable) {
|
||||||
|
t->setDeembeddingActive(true);
|
||||||
|
} else {
|
||||||
|
t->clearDeembedding();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNA::setAveragingMode(Averaging::Mode mode)
|
void VNA::setAveragingMode(Averaging::Mode mode)
|
||||||
|
@ -71,5 +71,7 @@
|
|||||||
<file>icons/definedShunt.svg</file>
|
<file>icons/definedShunt.svg</file>
|
||||||
<file>icons/definedThrough.png</file>
|
<file>icons/definedThrough.png</file>
|
||||||
<file>icons/definedThrough.svg</file>
|
<file>icons/definedThrough.svg</file>
|
||||||
|
<file>icons/deembedding_disabled.svg</file>
|
||||||
|
<file>icons/deembedding_enabled.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="20mm"
|
||||||
|
height="20mm"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
inkscape:version="1.2.2 (b0a8486541, 2022-12-01, custom)"
|
||||||
|
sodipodi:docname="deembedding_disabled.svg"
|
||||||
|
inkscape:export-filename="deembedding_disabled.svg"
|
||||||
|
inkscape:export-xdpi="17.1"
|
||||||
|
inkscape:export-ydpi="17.1"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="8"
|
||||||
|
inkscape:cx="32.625"
|
||||||
|
inkscape:cy="38.0625"
|
||||||
|
inkscape:window-width="1848"
|
||||||
|
inkscape:window-height="1016"
|
||||||
|
inkscape:window-x="1992"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<marker
|
||||||
|
style="overflow:visible"
|
||||||
|
id="TriangleStart"
|
||||||
|
refX="0"
|
||||||
|
refY="0"
|
||||||
|
orient="auto"
|
||||||
|
inkscape:stockid="TriangleStart"
|
||||||
|
markerWidth="3"
|
||||||
|
markerHeight="5.99999999"
|
||||||
|
viewBox="0 0 5.3244081 6.15538509"
|
||||||
|
inkscape:isstock="true"
|
||||||
|
inkscape:collect="always"
|
||||||
|
preserveAspectRatio="none">
|
||||||
|
<path
|
||||||
|
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:0.5pt"
|
||||||
|
d="M 2.885,0 -1.44,2.5 v -5 z"
|
||||||
|
id="path135" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;stroke-width:0.396875"
|
||||||
|
id="rect234"
|
||||||
|
width="15"
|
||||||
|
height="1"
|
||||||
|
x="2.5"
|
||||||
|
y="16.5" />
|
||||||
|
<path
|
||||||
|
style="fill:#000000;stroke-width:0.396875"
|
||||||
|
d="M 9.7834433,13.650246 V 3.2217677"
|
||||||
|
id="path453" />
|
||||||
|
<path
|
||||||
|
style="display:none;fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleStart)"
|
||||||
|
d="M 10.015208,14.285628 10,6"
|
||||||
|
id="path1395"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.8;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 11.015525,14.28403 V 7.997396 h 4.994451 L 9.99278,1.9801998 3.9615043,8.0114755 H 8.995516 v 6.2752715 z"
|
||||||
|
id="path13540" />
|
||||||
|
<path
|
||||||
|
style="display:inline;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||||
|
d="M 1.8217445,18.24796 18.5743,1.8171144"
|
||||||
|
id="path819-2"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
style="display:inline;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||||
|
d="M 1.8322416,18.193877 18.562413,1.8336946"
|
||||||
|
id="path819-2-6"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.4 KiB |
@ -0,0 +1,85 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="20mm"
|
||||||
|
height="20mm"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
inkscape:version="1.2.2 (b0a8486541, 2022-12-01, custom)"
|
||||||
|
sodipodi:docname="deembedding_enabled.svg"
|
||||||
|
inkscape:export-filename="deembedding_disabled.svg"
|
||||||
|
inkscape:export-xdpi="17.1"
|
||||||
|
inkscape:export-ydpi="17.1"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="8"
|
||||||
|
inkscape:cx="32.625"
|
||||||
|
inkscape:cy="38.0625"
|
||||||
|
inkscape:window-width="1848"
|
||||||
|
inkscape:window-height="1016"
|
||||||
|
inkscape:window-x="1992"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<marker
|
||||||
|
style="overflow:visible"
|
||||||
|
id="TriangleStart"
|
||||||
|
refX="0"
|
||||||
|
refY="0"
|
||||||
|
orient="auto"
|
||||||
|
inkscape:stockid="TriangleStart"
|
||||||
|
markerWidth="3"
|
||||||
|
markerHeight="5.99999999"
|
||||||
|
viewBox="0 0 5.3244081 6.15538509"
|
||||||
|
inkscape:isstock="true"
|
||||||
|
inkscape:collect="always"
|
||||||
|
preserveAspectRatio="none">
|
||||||
|
<path
|
||||||
|
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:0.5pt"
|
||||||
|
d="M 2.885,0 -1.44,2.5 v -5 z"
|
||||||
|
id="path135" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;stroke-width:0.396875"
|
||||||
|
id="rect234"
|
||||||
|
width="15"
|
||||||
|
height="1"
|
||||||
|
x="2.5"
|
||||||
|
y="16.5" />
|
||||||
|
<path
|
||||||
|
style="fill:#000000;stroke-width:0.396875"
|
||||||
|
d="M 9.7834433,13.650246 V 3.2217677"
|
||||||
|
id="path453" />
|
||||||
|
<path
|
||||||
|
style="display:none;fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleStart)"
|
||||||
|
d="M 10.015208,14.285628 10,6"
|
||||||
|
id="path1395"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.8;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 11.015525,14.28403 V 7.997396 h 4.994451 L 9.99278,1.9801998 3.9615043,8.0114755 H 8.995516 v 6.2752715 z"
|
||||||
|
id="path13540" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
Loading…
Reference in New Issue
Block a user