support saving of trace data in setup files
This commit is contained in:
parent
7d7bd3a44c
commit
4ad3d3ac54
@ -53,7 +53,7 @@ public:
|
|||||||
|
|
||||||
class Data {
|
class Data {
|
||||||
public:
|
public:
|
||||||
Data() : x(0){}
|
Data() : x(0), y(0){}
|
||||||
double x;
|
double x;
|
||||||
std::complex<double> y;
|
std::complex<double> y;
|
||||||
};
|
};
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "traceaxis.h"
|
#include "traceaxis.h"
|
||||||
#include "tracemodel.h"
|
#include "tracemodel.h"
|
||||||
#include "Math/parser/mpParser.h"
|
#include "Math/parser/mpParser.h"
|
||||||
|
#include "preferences.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -684,10 +685,6 @@ nlohmann::json Trace::toJSON()
|
|||||||
if(!JSONskipHash) {
|
if(!JSONskipHash) {
|
||||||
j["hash"] = toHash(true);
|
j["hash"] = toHash(true);
|
||||||
}
|
}
|
||||||
if(source == Source::Calibration) {
|
|
||||||
// calibration traces can't be saved
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
j["name"] = _name.toStdString();
|
j["name"] = _name.toStdString();
|
||||||
j["color"] = _color.name().toStdString();
|
j["color"] = _color.name().toStdString();
|
||||||
j["visible"] = visible;
|
j["visible"] = visible;
|
||||||
@ -717,7 +714,7 @@ nlohmann::json Trace::toJSON()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Source::Calibration:
|
case Source::Calibration:
|
||||||
// Skip for now, TODO?
|
j["type"] = "Calibration";
|
||||||
break;
|
break;
|
||||||
case Source::Last:
|
case Source::Last:
|
||||||
break;
|
break;
|
||||||
@ -725,6 +722,19 @@ nlohmann::json Trace::toJSON()
|
|||||||
j["velocityFactor"] = vFactor;
|
j["velocityFactor"] = vFactor;
|
||||||
j["reflection"] = reflection;
|
j["reflection"] = reflection;
|
||||||
|
|
||||||
|
auto &pref = Preferences::getInstance();
|
||||||
|
if(pref.Debug.saveTraceData) {
|
||||||
|
nlohmann::json jdata;
|
||||||
|
for(const auto &d : data) {
|
||||||
|
nlohmann::json jpoint;
|
||||||
|
jpoint["x"] = d.x;
|
||||||
|
jpoint["real"] = d.y.real();
|
||||||
|
jpoint["imag"] = d.y.imag();
|
||||||
|
jdata.push_back(jpoint);
|
||||||
|
}
|
||||||
|
j["data"] = jdata;
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@ -757,6 +767,16 @@ void Trace::fromJSON(nlohmann::json j)
|
|||||||
_color = QColor(QString::fromStdString(j.value("color", "yellow")));
|
_color = QColor(QString::fromStdString(j.value("color", "yellow")));
|
||||||
visible = j.value("visible", true);
|
visible = j.value("visible", true);
|
||||||
auto type = QString::fromStdString(j.value("type", "Live"));
|
auto type = QString::fromStdString(j.value("type", "Live"));
|
||||||
|
if(j.contains("data")) {
|
||||||
|
// Trace data is contained in the json, load now
|
||||||
|
clear();
|
||||||
|
for(auto jpoint : j["data"]) {
|
||||||
|
Data d;
|
||||||
|
d.x = jpoint.value("x", 0.0);
|
||||||
|
d.y = complex<double>(jpoint.value("real", 0.0), jpoint.value("imag", 0.0));
|
||||||
|
data.push_back(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
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) {
|
||||||
@ -776,6 +796,7 @@ void Trace::fromJSON(nlohmann::json j)
|
|||||||
_liveType = j.value("livetype", LivedataType::Overwrite);
|
_liveType = j.value("livetype", LivedataType::Overwrite);
|
||||||
paused = j.value("paused", false);
|
paused = j.value("paused", false);
|
||||||
} else if(type == "Touchstone" || type == "File") {
|
} else if(type == "Touchstone" || type == "File") {
|
||||||
|
source = Source::File;
|
||||||
auto filename = QString::fromStdString(j.value("filename", ""));
|
auto filename = QString::fromStdString(j.value("filename", ""));
|
||||||
fileParameter = j.value("parameter", 0);
|
fileParameter = j.value("parameter", 0);
|
||||||
try {
|
try {
|
||||||
@ -788,10 +809,10 @@ void Trace::fromJSON(nlohmann::json j)
|
|||||||
fillFromTouchstone(t, fileParameter);
|
fillFromTouchstone(t, fileParameter);
|
||||||
}
|
}
|
||||||
} catch (const exception &e) {
|
} catch (const exception &e) {
|
||||||
std::string what = e.what();
|
qWarning() << "Failed to create from file:" << QString::fromStdString(e.what());
|
||||||
throw runtime_error("Failed to create from file:" + what);
|
|
||||||
}
|
}
|
||||||
} else if(type == "Math") {
|
} else if(type == "Math") {
|
||||||
|
source = Source::Math;
|
||||||
mathFormula = QString::fromStdString(j.value("expression", ""));
|
mathFormula = QString::fromStdString(j.value("expression", ""));
|
||||||
if(j.contains("sources")) {
|
if(j.contains("sources")) {
|
||||||
for(auto js : j["sources"]) {
|
for(auto js : j["sources"]) {
|
||||||
@ -804,6 +825,9 @@ void Trace::fromJSON(nlohmann::json j)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fromMath();
|
fromMath();
|
||||||
|
} else if(type == "Calibration") {
|
||||||
|
source = Source::Calibration;
|
||||||
|
// data has already been loaded if present in the file
|
||||||
}
|
}
|
||||||
vFactor = j.value("velocityFactor", 0.66);
|
vFactor = j.value("velocityFactor", 0.66);
|
||||||
reflection = j.value("reflection", false);
|
reflection = j.value("reflection", false);
|
||||||
@ -841,6 +865,8 @@ void Trace::fromJSON(nlohmann::json j)
|
|||||||
updateLastMath(mathOps.rbegin());
|
updateLastMath(mathOps.rbegin());
|
||||||
}
|
}
|
||||||
enableMath(j.value("math_enabled", true));
|
enableMath(j.value("math_enabled", true));
|
||||||
|
// indicate successful loading of trace data
|
||||||
|
success();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Trace::toHash(bool forceUpdate)
|
unsigned int Trace::toHash(bool forceUpdate)
|
||||||
|
@ -63,12 +63,13 @@ TraceEditDialog::TraceEditDialog(Trace &t, QWidget *parent) :
|
|||||||
|
|
||||||
ui->GSource->setId(ui->bLive, 0);
|
ui->GSource->setId(ui->bLive, 0);
|
||||||
ui->GSource->setId(ui->bFile, 1);
|
ui->GSource->setId(ui->bFile, 1);
|
||||||
ui->GSource->setId(ui->bFile, 2);
|
ui->GSource->setId(ui->bMath, 2);
|
||||||
|
|
||||||
if(t.getSource() == Trace::Source::Calibration) {
|
if(t.getSource() == Trace::Source::Calibration) {
|
||||||
// prevent editing imported calibration traces (and csv files for now)
|
// prevent editing imported calibration traces (and csv files for now)
|
||||||
ui->bLive->setEnabled(false);
|
ui->bLive->setEnabled(false);
|
||||||
ui->bFile->setEnabled(false);
|
ui->bFile->setEnabled(false);
|
||||||
|
ui->bMath->setEnabled(false);
|
||||||
ui->CLiveType->setEnabled(false);
|
ui->CLiveType->setEnabled(false);
|
||||||
ui->CLiveParam->setEnabled(false);
|
ui->CLiveParam->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QStackedWidget" name="stack">
|
<widget class="QStackedWidget" name="stack">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>3</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="LivePage">
|
<widget class="QWidget" name="LivePage">
|
||||||
<layout class="QFormLayout" name="formLayout_2">
|
<layout class="QFormLayout" name="formLayout_2">
|
||||||
@ -398,6 +398,11 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>ColorPickerButton</class>
|
||||||
|
<extends>QPushButton</extends>
|
||||||
|
<header>CustomWidgets/colorpickerbutton.h</header>
|
||||||
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>SIUnitEdit</class>
|
<class>SIUnitEdit</class>
|
||||||
<extends>QLineEdit</extends>
|
<extends>QLineEdit</extends>
|
||||||
@ -409,11 +414,6 @@
|
|||||||
<header>CustomWidgets/touchstoneimport.h</header>
|
<header>CustomWidgets/touchstoneimport.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
|
||||||
<class>ColorPickerButton</class>
|
|
||||||
<extends>QPushButton</extends>
|
|
||||||
<header>CustomWidgets/colorpickerbutton.h</header>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>CSVImport</class>
|
<class>CSVImport</class>
|
||||||
<extends>QWidget</extends>
|
<extends>QWidget</extends>
|
||||||
|
@ -117,7 +117,6 @@ void TracePolar::setAuto(bool horizontally, bool vertically)
|
|||||||
|
|
||||||
bool TracePolar::positionWithinGraphArea(const QPoint &p)
|
bool TracePolar::positionWithinGraphArea(const QPoint &p)
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
auto coord = pixelToData(p);
|
auto coord = pixelToData(p);
|
||||||
if(abs(coord) <= edgeReflection) {
|
if(abs(coord) <= edgeReflection) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -89,13 +89,11 @@ VNA::VNA(AppWindow *window, QString name)
|
|||||||
calMenu->addSeparator();
|
calMenu->addSeparator();
|
||||||
|
|
||||||
connect(calLoad, &QAction::triggered, [=](){
|
connect(calLoad, &QAction::triggered, [=](){
|
||||||
LoadCalibration("");
|
LoadCalibration();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(saveCal, &QAction::triggered, [=](){
|
connect(saveCal, &QAction::triggered, [=](){
|
||||||
if(cal.toFile()) {
|
SaveCalibration();
|
||||||
UpdateStatusbar();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(&cal, &Calibration::startMeasurements, this, &VNA::StartCalibrationMeasurements);
|
connect(&cal, &Calibration::startMeasurements, this, &VNA::StartCalibrationMeasurements);
|
||||||
@ -705,7 +703,7 @@ void VNA::shutdown()
|
|||||||
if(cal.hasUnsavedChanges() && cal.getCaltype().type != Calibration::Type::None) {
|
if(cal.hasUnsavedChanges() && cal.getCaltype().type != Calibration::Type::None) {
|
||||||
auto save = InformationBox::AskQuestion("Save calibration?", "The calibration contains data that has not been saved yet. Do you want to save it before exiting?", false);
|
auto save = InformationBox::AskQuestion("Save calibration?", "The calibration contains data that has not been saved yet. Do you want to save it before exiting?", false);
|
||||||
if(save) {
|
if(save) {
|
||||||
cal.toFile();
|
SaveCalibration();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1740,3 +1738,8 @@ bool VNA::LoadCalibration(QString filename)
|
|||||||
{
|
{
|
||||||
return cal.fromFile(filename);
|
return cal.fromFile(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VNA::SaveCalibration(QString filename)
|
||||||
|
{
|
||||||
|
return cal.toFile(filename);
|
||||||
|
}
|
||||||
|
@ -76,7 +76,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool LoadCalibration(QString filename);
|
bool LoadCalibration(QString filename = "");
|
||||||
|
bool SaveCalibration(QString filename = "");
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void NewDatapoint(VirtualDevice::VNAMeasurement m);
|
void NewDatapoint(VirtualDevice::VNAMeasurement m);
|
||||||
|
@ -82,6 +82,7 @@
|
|||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Help</string>
|
<string>Help</string>
|
||||||
</property>
|
</property>
|
||||||
|
<addaction name="actionCreate_Debug_Data"/>
|
||||||
<addaction name="actionAbout"/>
|
<addaction name="actionAbout"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuView">
|
<widget class="QMenu" name="menuView">
|
||||||
@ -234,6 +235,11 @@
|
|||||||
<string>View USB log</string>
|
<string>View USB log</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionCreate_Debug_Data">
|
||||||
|
<property name="text">
|
||||||
|
<string>Create Debug Data</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="icons.qrc"/>
|
<include location="icons.qrc"/>
|
||||||
|
@ -388,6 +388,7 @@ void PreferencesDialog::setInitialGUIState()
|
|||||||
ui->SCPIServerPort->setValue(p->SCPIServer.port);
|
ui->SCPIServerPort->setValue(p->SCPIServer.port);
|
||||||
|
|
||||||
ui->DebugMaxUSBlogSize->setValue(p->Debug.USBlogSizeLimit);
|
ui->DebugMaxUSBlogSize->setValue(p->Debug.USBlogSizeLimit);
|
||||||
|
ui->DebugSaveTraceData->setChecked(p->Debug.saveTraceData);
|
||||||
|
|
||||||
for(auto cd : p->compoundDevices) {
|
for(auto cd : p->compoundDevices) {
|
||||||
ui->compoundList->addItem(cd->getDesription());
|
ui->compoundList->addItem(cd->getDesription());
|
||||||
@ -491,6 +492,7 @@ void PreferencesDialog::updateFromGUI()
|
|||||||
p->SCPIServer.port = ui->SCPIServerPort->value();
|
p->SCPIServer.port = ui->SCPIServerPort->value();
|
||||||
|
|
||||||
p->Debug.USBlogSizeLimit = ui->DebugMaxUSBlogSize->value();
|
p->Debug.USBlogSizeLimit = ui->DebugMaxUSBlogSize->value();
|
||||||
|
p->Debug.saveTraceData = ui->DebugSaveTraceData->isChecked();
|
||||||
|
|
||||||
p->nonTrivialWriting();
|
p->nonTrivialWriting();
|
||||||
}
|
}
|
||||||
|
@ -162,6 +162,7 @@ public:
|
|||||||
} SCPIServer;
|
} SCPIServer;
|
||||||
struct {
|
struct {
|
||||||
double USBlogSizeLimit;
|
double USBlogSizeLimit;
|
||||||
|
bool saveTraceData;
|
||||||
} Debug;
|
} Debug;
|
||||||
|
|
||||||
bool TCPoverride; // in case of manual port specification via command line
|
bool TCPoverride; // in case of manual port specification via command line
|
||||||
@ -268,6 +269,7 @@ private:
|
|||||||
{&SCPIServer.enabled, "SCPIServer.enabled", true},
|
{&SCPIServer.enabled, "SCPIServer.enabled", true},
|
||||||
{&SCPIServer.port, "SCPIServer.port", 19542},
|
{&SCPIServer.port, "SCPIServer.port", 19542},
|
||||||
{&Debug.USBlogSizeLimit, "Debug.USBlogSizeLimit", 10000000.0},
|
{&Debug.USBlogSizeLimit, "Debug.USBlogSizeLimit", 10000000.0},
|
||||||
|
{&Debug.saveTraceData, "Debug.saveTraceData", false},
|
||||||
{&compoundDeviceJSON, "compoundDeviceJSON", "[]"},
|
{&compoundDeviceJSON, "compoundDeviceJSON", "[]"},
|
||||||
}};
|
}};
|
||||||
};
|
};
|
||||||
|
@ -712,8 +712,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>565</width>
|
<width>749</width>
|
||||||
<height>863</height>
|
<height>846</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_21">
|
<layout class="QVBoxLayout" name="verticalLayout_21">
|
||||||
@ -1033,8 +1033,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>553</width>
|
<width>749</width>
|
||||||
<height>969</height>
|
<height>952</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_22">
|
<layout class="QVBoxLayout" name="verticalLayout_22">
|
||||||
@ -1961,6 +1961,22 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_24">
|
||||||
|
<property name="title">
|
||||||
|
<string>Trace saving</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_31">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="DebugSaveTraceData">
|
||||||
|
<property name="text">
|
||||||
|
<string>Include datapoints</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_9">
|
<spacer name="verticalSpacer_9">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
Loading…
Reference in New Issue
Block a user