support saving of trace data in setup files

This commit is contained in:
Jan Käberich 2022-11-09 23:29:37 +01:00
parent 7d7bd3a44c
commit 4ad3d3ac54
11 changed files with 82 additions and 26 deletions

View File

@ -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;
}; };

View File

@ -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)

View File

@ -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);
} }

View File

@ -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>

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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"/>

View File

@ -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();
} }

View File

@ -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", "[]"},
}}; }};
}; };

View File

@ -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">