LibreVNA/Software/PC_Application/Traces/Math/expression.cpp
2022-03-03 12:28:59 +01:00

139 lines
3.2 KiB
C++

#include "expression.h"
#include "ui_expressiondialog.h"
#include "Traces/trace.h"
#include "ui_expressionexplanationwidget.h"
#include "appwindow.h"
#include <QWidget>
#include <QDebug>
using namespace mup;
using namespace std;
Math::Expression::Expression()
{
parser = new ParserX(pckCOMMON | pckUNIT | pckCOMPLEX);
parser->DefineVar("x", Variable(&x));
expressionChanged();
}
Math::Expression::~Expression()
{
delete parser;
}
TraceMath::DataType Math::Expression::outputType(TraceMath::DataType inputType)
{
return inputType;
}
QString Math::Expression::description()
{
return "Custom expression: " + exp;
}
void Math::Expression::edit()
{
auto d = new QDialog();
auto ui = new Ui::ExpressionDialog;
ui->setupUi(d);
connect(d, &QDialog::finished, [=](){
delete ui;
});
ui->expEdit->setText(exp);
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){
exp = ui->expEdit->text();
expressionChanged();
});
switch(dataType) {
case DataType::Frequency: ui->stackedWidget->setCurrentIndex(0); break;
case DataType::Time: ui->stackedWidget->setCurrentIndex(1); break;
case DataType::Power: ui->stackedWidget->setCurrentIndex(2); break;
default: break;
}
if(AppWindow::showGUI()) {
d->show();
}
}
QWidget *Math::Expression::createExplanationWidget()
{
auto w = new QWidget();
auto ui = new Ui::ExpressionExplanationWidget;
ui->setupUi(w);
connect(w, &QWidget::destroyed, [=](){
delete ui;
});
return w;
}
nlohmann::json Math::Expression::toJSON()
{
nlohmann::json j;
j["exp"] = exp.toStdString();
return j;
}
void Math::Expression::fromJSON(nlohmann::json j)
{
exp = QString::fromStdString(j.value("exp", ""));
expressionChanged();
}
void Math::Expression::inputSamplesChanged(unsigned int begin, unsigned int end)
{
auto in = input->rData();
data.resize(in.size());
try {
for(unsigned int i=begin;i<end;i++) {
t = in[i].x;
f = in[i].x;
P = in[i].x;
w = in[i].x * 2 * M_PI;
d = root()->timeToDistance(t);
x = in[i].y;
Value res = parser->Eval();
data[i].x = in[i].x;
data[i].y = res.GetComplex();
}
success();
emit outputSamplesChanged(begin, end);
} catch (const ParserError &e) {
error(QString::fromStdString(e.GetMsg()));
}
}
void Math::Expression::expressionChanged()
{
if(exp.isEmpty()) {
error("Empty expression");
return;
}
parser->SetExpr(exp.toStdString());
parser->RemoveVar("t");
parser->RemoveVar("d");
parser->RemoveVar("f");
parser->RemoveVar("w");
parser->RemoveVar("P");
switch(dataType) {
case DataType::Time:
parser->DefineVar("t", Variable(&t));
parser->DefineVar("d", Variable(&d));
break;
case DataType::Frequency:
parser->DefineVar("f", Variable(&f));
parser->DefineVar("w", Variable(&w));
break;
case DataType::Power:
parser->DefineVar("P", Variable(&P));
break;
default:
break;
}
if(input) {
inputSamplesChanged(0, input->rData().size());
}
}