#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 #include 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; } e->setTrace(i%2+1, i/2+1, traces[i]); } 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 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 &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 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()+"\""); } } }