2022-10-01 23:10:44 +08:00
|
|
|
#include "tracewidgetvna.h"
|
|
|
|
|
|
|
|
#include "Traces/traceimportdialog.h"
|
|
|
|
#include "Traces/tracetouchstoneexport.h"
|
|
|
|
#include "Traces/tracecsvexport.h"
|
|
|
|
#include "ui_tracewidget.h"
|
|
|
|
#include "ui_s2pImportOptions.h"
|
|
|
|
#include "CustomWidgets/informationbox.h"
|
|
|
|
#include "appwindow.h"
|
|
|
|
|
|
|
|
#include <QFileDialog>
|
|
|
|
#include <QMenu>
|
|
|
|
|
|
|
|
TraceWidgetVNA::TraceWidgetVNA(TraceModel &model, Calibration &cal, Deembedding &deembed, QWidget *parent)
|
|
|
|
: TraceWidget(model, parent),
|
|
|
|
cal(cal),
|
|
|
|
deembed(deembed)
|
|
|
|
{
|
|
|
|
auto exportMenu = new QMenu();
|
|
|
|
auto exportTouchstone = new QAction("Touchstone");
|
|
|
|
auto exportCSV = new QAction("CSV");
|
|
|
|
exportMenu->addAction(exportTouchstone);
|
|
|
|
exportMenu->addAction(exportCSV);
|
|
|
|
|
|
|
|
ui->bExport->setMenu(exportMenu);
|
|
|
|
|
|
|
|
connect(exportTouchstone, &QAction::triggered, [&]() {
|
|
|
|
auto e = new TraceTouchstoneExport(model);
|
|
|
|
// Attempt to set default traces (this will result in correctly populated
|
|
|
|
// 2 port export if the initial 4 traces have not been modified)
|
|
|
|
e->setPortNum(2);
|
|
|
|
auto traces = model.getTraces();
|
|
|
|
for(unsigned int i=0;i<4;i++) {
|
|
|
|
if(i >= traces.size()) {
|
|
|
|
break;
|
|
|
|
}
|
2022-11-09 19:33:14 +08:00
|
|
|
e->setTrace(i%2+1, i/2+1, traces[i]);
|
2022-10-01 23:10:44 +08:00
|
|
|
}
|
|
|
|
if(AppWindow::showGUI()) {
|
|
|
|
e->show();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
connect(exportCSV, &QAction::triggered, [&]() {
|
|
|
|
auto e = new TraceCSVExport(model);
|
|
|
|
if(AppWindow::showGUI()) {
|
|
|
|
e->show();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void TraceWidgetVNA::importDialog()
|
|
|
|
{
|
|
|
|
auto filename = QFileDialog::getOpenFileName(nullptr, "Open measurement file", "", "Touchstone files (*.s1p *.s2p *.s3p *.s4p);;CSV files (*.csv)", nullptr, QFileDialog::DontUseNativeDialog);
|
|
|
|
if (!filename.isEmpty()) {
|
|
|
|
try {
|
|
|
|
std::vector<Trace*> traces;
|
|
|
|
int touchstonePorts = 0;
|
|
|
|
QString prefix = QString();
|
|
|
|
if(filename.endsWith(".csv")) {
|
|
|
|
auto csv = CSV::fromFile(filename);
|
|
|
|
traces = Trace::createFromCSV(csv);
|
|
|
|
} else {
|
|
|
|
// must be a touchstone file
|
|
|
|
auto t = Touchstone::fromFile(filename.toStdString());
|
|
|
|
traces = Trace::createFromTouchstone(t);
|
|
|
|
touchstonePorts = t.ports();
|
|
|
|
}
|
|
|
|
// contruct prefix from filename
|
|
|
|
prefix = filename;
|
|
|
|
// remove any directory names (keep only the filename itself)
|
|
|
|
int lastSlash = qMax(prefix.lastIndexOf('/'), prefix.lastIndexOf('\\'));
|
|
|
|
if(lastSlash != -1) {
|
|
|
|
prefix.remove(0, lastSlash + 1);
|
|
|
|
}
|
|
|
|
// remove file type
|
|
|
|
prefix.truncate(prefix.indexOf('.'));
|
|
|
|
prefix.append("_");
|
|
|
|
auto i = new TraceImportDialog(model, traces, prefix);
|
|
|
|
if(AppWindow::showGUI()) {
|
|
|
|
i->show();
|
|
|
|
}
|
|
|
|
// potential candidate to process via calibration/de-embedding
|
|
|
|
connect(i, &TraceImportDialog::importFinsished, [=](const std::vector<Trace*> &traces) {
|
|
|
|
if(traces.size() == touchstonePorts*touchstonePorts) {
|
|
|
|
// all traces imported, can calculate calibration/de-embedding
|
|
|
|
bool calAvailable = cal.getNumPoints() > 0;
|
|
|
|
bool deembedAvailable = deembed.getOptions().size() > 0;
|
|
|
|
if(calAvailable || deembedAvailable) {
|
|
|
|
// check if user wants to apply either one to the imported traces
|
|
|
|
auto dialog = new QDialog();
|
|
|
|
auto ui = new Ui::s2pImportOptions;
|
|
|
|
ui->setupUi(dialog);
|
|
|
|
connect(dialog, &QDialog::finished, [=](){
|
|
|
|
delete ui;
|
|
|
|
});
|
|
|
|
ui->applyCal->setEnabled(calAvailable);
|
|
|
|
ui->deembed->setEnabled(deembedAvailable);
|
|
|
|
bool applyCal = false;
|
|
|
|
bool applyDeembed = false;
|
|
|
|
connect(ui->applyCal, &QCheckBox::toggled, [&](bool checked) {
|
|
|
|
applyCal = checked;
|
|
|
|
});
|
|
|
|
connect(ui->deembed, &QCheckBox::toggled, [&](bool checked) {
|
|
|
|
applyDeembed = checked;
|
|
|
|
});
|
|
|
|
if(AppWindow::showGUI()) {
|
|
|
|
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) {
|
|
|
|
cal.correctTraces(set);
|
|
|
|
}
|
|
|
|
if(applyDeembed) {
|
|
|
|
deembed.Deembed(set);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} catch(const std::exception& e) {
|
|
|
|
InformationBox::ShowError("Failed to import file", QString("Attempt to import file ended with error: \"") + e.what()+"\"");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|