2022-05-18 02:07:40 +08:00
# include " vna.h "
2021-10-21 19:00:34 +08:00
# include "unit.h"
# include "CustomWidgets/toggleswitch.h"
# include "Device/manualcontroldialog.h"
# include "Traces/tracemodel.h"
# include "tracewidgetvna.h"
# include "Traces/tracesmithchart.h"
# include "Traces/tracexyplot.h"
# include "Traces/traceimportdialog.h"
# include "CustomWidgets/tilewidget.h"
# include "CustomWidgets/siunitedit.h"
# include "Traces/Marker/markerwidget.h"
# include "Tools/impedancematchdialog.h"
# include "ui_main.h"
# include "Device/firmwareupdatedialog.h"
# include "preferences.h"
# include "Generator/signalgenwidget.h"
# include "CustomWidgets/informationbox.h"
# include "Deembedding/manualdeembeddingdialog.h"
# include "Calibration/manualcalibrationdialog.h"
2022-09-12 05:22:11 +08:00
# include "Calibration/LibreCAL/librecaldialog.h"
2022-03-07 06:01:11 +08:00
# include "Util/util.h"
2022-03-18 01:24:18 +08:00
# include "Tools/parameters.h"
2021-10-21 19:00:34 +08:00
2020-08-31 04:03:41 +08:00
# include <QGridLayout>
# include <QVBoxLayout>
# include <QHBoxLayout>
# include <QPushButton>
# include <math.h>
# include <QToolBar>
# include <QMenu>
# include <QToolButton>
# include <QActionGroup>
# include <QSpinBox>
# include <QCheckBox>
# include <QComboBox>
# include <QSettings>
# include <algorithm>
# include <QMessageBox>
# include <QFileDialog>
# include <QFile>
# include <iostream>
# include <fstream>
# include <QDateTime>
# include <QDockWidget>
2021-10-21 19:00:34 +08:00
# include <queue>
2020-09-12 05:07:15 +08:00
# include <QDesktopWidget>
# include <QApplication>
2020-09-13 20:44:45 +08:00
# include <QActionGroup>
2020-11-11 02:16:16 +08:00
# include <QErrorMessage>
2020-11-22 07:41:42 +08:00
# include <QDebug>
2020-08-31 04:03:41 +08:00
2022-04-04 05:34:18 +08:00
VNA : : VNA ( AppWindow * window , QString name )
: Mode ( window , name , " VNA " ) ,
2021-02-11 23:59:59 +08:00
deembedding ( traceModel ) ,
2021-12-11 03:46:04 +08:00
deembedding_active ( false ) ,
2020-09-13 20:44:45 +08:00
central ( new TileWidget ( traceModel ) )
2020-08-31 04:03:41 +08:00
{
averages = 1 ;
2022-05-18 02:07:40 +08:00
singleSweep = false ;
2020-08-31 04:03:41 +08:00
calMeasuring = false ;
2022-01-08 00:54:26 +08:00
calWaitFirst = false ;
2020-08-31 04:03:41 +08:00
calDialog . reset ( ) ;
2022-03-08 05:51:56 +08:00
changingSettings = false ;
2021-12-11 03:46:04 +08:00
settings . sweepType = SweepType : : Frequency ;
2022-06-20 07:02:09 +08:00
settings . zerospan = false ;
2020-08-31 04:03:41 +08:00
2022-01-31 00:40:46 +08:00
traceModel . setSource ( TraceModel : : DataSource : : VNA ) ;
2020-09-12 05:07:15 +08:00
// Create default traces
2022-08-09 00:08:40 +08:00
createDefaultTracesAndGraphs ( 2 ) ;
2020-09-12 05:07:15 +08:00
2020-09-16 05:22:08 +08:00
connect ( & traceModel , & TraceModel : : requiredExcitation , this , & VNA : : ExcitationRequired ) ;
2020-09-13 20:44:45 +08:00
// Create menu entries and connections
2020-11-01 06:03:34 +08:00
auto calMenu = new QMenu ( " Calibration " , window ) ;
2020-09-13 20:44:45 +08:00
window - > menuBar ( ) - > insertMenu ( window - > getUi ( ) - > menuWindow - > menuAction ( ) , calMenu ) ;
actions . insert ( calMenu - > menuAction ( ) ) ;
2020-11-11 02:16:16 +08:00
auto calLoad = calMenu - > addAction ( " Load " ) ;
saveCal = calMenu - > addAction ( " Save " ) ;
calMenu - > addSeparator ( ) ;
saveCal - > setEnabled ( false ) ;
connect ( calLoad , & QAction : : triggered , [ = ] ( ) {
2022-03-01 19:31:38 +08:00
LoadCalibration ( " " ) ;
2020-11-11 02:16:16 +08:00
} ) ;
connect ( saveCal , & QAction : : triggered , [ = ] ( ) {
2022-08-30 02:07:07 +08:00
if ( cal . toFile ( ) ) {
2022-01-22 05:33:58 +08:00
UpdateStatusbar ( ) ;
2020-12-08 03:21:24 +08:00
}
2020-11-11 02:16:16 +08:00
} ) ;
2022-08-30 02:07:07 +08:00
connect ( & cal , & Calibration : : startMeasurements , this , & VNA : : StartCalibrationMeasurements ) ;
2022-08-29 04:06:16 +08:00
2020-11-11 02:16:16 +08:00
auto calData = calMenu - > addAction ( " Calibration Measurements " ) ;
2020-09-13 20:44:45 +08:00
connect ( calData , & QAction : : triggered , [ = ] ( ) {
2022-08-30 02:07:07 +08:00
cal . edit ( ) ;
2022-08-29 04:06:16 +08:00
// StartCalibrationDialog();
2020-08-31 04:03:41 +08:00
} ) ;
2020-09-13 20:44:45 +08:00
auto calEditKit = calMenu - > addAction ( " Edit Calibration Kit " ) ;
connect ( calEditKit , & QAction : : triggered , [ = ] ( ) {
2022-08-30 02:07:07 +08:00
cal . getKit ( ) . edit ( ) ;
2022-08-29 04:06:16 +08:00
// cal.getCalibrationKit().edit([=](){
// if(calValid) {
// ApplyCalibration(cal.getType());
// }
// });
2020-09-13 20:44:45 +08:00
} ) ;
2020-11-28 01:18:31 +08:00
2022-09-12 05:22:11 +08:00
auto calElectronic = calMenu - > addAction ( " Electronic Calibration " ) ;
connect ( calElectronic , & QAction : : triggered , [ = ] ( ) {
auto d = new LibreCALDialog ( & cal ) ;
d - > show ( ) ;
} ) ;
2020-11-28 01:18:31 +08:00
calMenu - > addSeparator ( ) ;
auto calImportTerms = calMenu - > addAction ( " Import error terms as traces " ) ;
calImportTerms - > setEnabled ( false ) ;
connect ( calImportTerms , & QAction : : triggered , [ = ] ( ) {
auto import = new TraceImportDialog ( traceModel , cal . getErrorTermTraces ( ) ) ;
2022-03-03 19:28:59 +08:00
if ( AppWindow : : showGUI ( ) ) {
import - > show ( ) ;
}
2020-11-28 01:18:31 +08:00
} ) ;
auto calImportMeas = calMenu - > addAction ( " Import measurements as traces " ) ;
calImportMeas - > setEnabled ( false ) ;
connect ( calImportMeas , & QAction : : triggered , [ = ] ( ) {
auto import = new TraceImportDialog ( traceModel , cal . getMeasurementTraces ( ) ) ;
2022-03-03 19:28:59 +08:00
if ( AppWindow : : showGUI ( ) ) {
import - > show ( ) ;
}
2020-11-28 01:18:31 +08:00
} ) ;
2021-03-12 04:52:58 +08:00
calMenu - > addSeparator ( ) ;
auto calApplyToTraces = calMenu - > addAction ( " Apply to traces... " ) ;
calApplyToTraces - > setEnabled ( false ) ;
connect ( calApplyToTraces , & QAction : : triggered , [ = ] ( ) {
auto manualCalibration = new ManualCalibrationDialog ( traceModel , & cal ) ;
2022-03-03 19:28:59 +08:00
if ( AppWindow : : showGUI ( ) ) {
manualCalibration - > show ( ) ;
}
2021-03-12 04:52:58 +08:00
} ) ;
2021-01-30 04:44:44 +08:00
// portExtension.setCalkit(&cal.getCalibrationKit());
2020-09-13 20:44:45 +08:00
2021-03-12 04:52:58 +08:00
// De-embedding menu
auto menuDeembed = new QMenu ( " De-embedding " , window ) ;
window - > menuBar ( ) - > insertMenu ( window - > getUi ( ) - > menuWindow - > menuAction ( ) , menuDeembed ) ;
2021-03-23 04:28:30 +08:00
actions . insert ( menuDeembed - > menuAction ( ) ) ;
2021-03-12 04:52:58 +08:00
auto confDeembed = menuDeembed - > addAction ( " Setup... " ) ;
connect ( confDeembed , & QAction : : triggered , & deembedding , & Deembedding : : configure ) ;
enableDeembeddingAction = menuDeembed - > addAction ( " De-embed VNA samples " ) ;
enableDeembeddingAction - > setCheckable ( true ) ;
enableDeembeddingAction - > setEnabled ( false ) ;
connect ( enableDeembeddingAction , & QAction : : toggled , this , & VNA : : EnableDeembedding ) ;
auto manualDeembed = menuDeembed - > addAction ( " De-embed traces... " ) ;
manualDeembed - > setEnabled ( false ) ;
connect ( manualDeembed , & QAction : : triggered , [ = ] ( ) {
auto manualDeembedding = new ManualDeembeddingDialog ( traceModel , & deembedding ) ;
2022-03-03 19:28:59 +08:00
if ( AppWindow : : showGUI ( ) ) {
manualDeembedding - > show ( ) ;
}
2021-03-12 04:52:58 +08:00
} ) ;
connect ( & deembedding , & Deembedding : : optionAdded , [ = ] ( ) {
EnableDeembedding ( true ) ;
enableDeembeddingAction - > setEnabled ( true ) ;
manualDeembed - > setEnabled ( true ) ;
} ) ;
connect ( & deembedding , & Deembedding : : allOptionsCleared , [ = ] ( ) {
EnableDeembedding ( false ) ;
enableDeembeddingAction - > setEnabled ( false ) ;
manualDeembed - > setEnabled ( false ) ;
} ) ;
2020-09-13 20:44:45 +08:00
// Tools menu
2020-11-01 06:03:34 +08:00
auto toolsMenu = new QMenu ( " Tools " , window ) ;
2020-09-13 20:44:45 +08:00
window - > menuBar ( ) - > insertMenu ( window - > getUi ( ) - > menuWindow - > menuAction ( ) , toolsMenu ) ;
actions . insert ( toolsMenu - > menuAction ( ) ) ;
auto impedanceMatching = toolsMenu - > addAction ( " Impedance Matching " ) ;
connect ( impedanceMatching , & QAction : : triggered , this , & VNA : : StartImpedanceMatching ) ;
2020-11-01 06:03:34 +08:00
defaultCalMenu = new QMenu ( " Default Calibration " , window ) ;
2020-09-14 00:01:32 +08:00
assignDefaultCal = defaultCalMenu - > addAction ( " Assign... " ) ;
removeDefaultCal = defaultCalMenu - > addAction ( " Remove " ) ;
removeDefaultCal - > setEnabled ( false ) ;
defaultCalMenu - > setEnabled ( false ) ;
actions . insert ( window - > getUi ( ) - > menuDevice - > addSeparator ( ) ) ;
window - > getUi ( ) - > menuDevice - > addMenu ( defaultCalMenu ) ;
actions . insert ( defaultCalMenu - > menuAction ( ) ) ;
connect ( assignDefaultCal , & QAction : : triggered , [ = ] ( ) {
2020-09-13 20:44:45 +08:00
if ( window - > getDevice ( ) ) {
auto key = " DefaultCalibration " + window - > getDevice ( ) - > serial ( ) ;
2020-08-31 04:03:41 +08:00
QSettings settings ;
auto filename = QFileDialog : : getOpenFileName ( nullptr , " Load calibration data " , settings . value ( key ) . toString ( ) , " Calibration files (*.cal) " , nullptr , QFileDialog : : DontUseNativeDialog ) ;
if ( ! filename . isEmpty ( ) ) {
settings . setValue ( key , filename ) ;
2020-09-14 00:01:32 +08:00
removeDefaultCal - > setEnabled ( true ) ;
2020-08-31 04:03:41 +08:00
}
}
} ) ;
2020-09-14 00:01:32 +08:00
connect ( removeDefaultCal , & QAction : : triggered , [ = ] ( ) {
2020-08-31 04:03:41 +08:00
QSettings settings ;
2020-09-13 20:44:45 +08:00
settings . remove ( " DefaultCalibration " + window - > getDevice ( ) - > serial ( ) ) ;
2020-09-14 00:01:32 +08:00
removeDefaultCal - > setEnabled ( false ) ;
2020-08-31 04:03:41 +08:00
} ) ;
// Sweep toolbar
2020-09-13 20:44:45 +08:00
auto tb_sweep = new QToolBar ( " Sweep " ) ;
2021-07-10 00:42:22 +08:00
std : : vector < QAction * > frequencySweepActions ;
std : : vector < QAction * > powerSweepActions ;
tb_sweep - > addWidget ( new QLabel ( " Sweep type: " ) ) ;
auto cbSweepType = new QComboBox ( ) ;
cbSweepType - > addItem ( " Frequency " ) ;
cbSweepType - > addItem ( " Power " ) ;
tb_sweep - > addWidget ( cbSweepType ) ;
2022-05-18 02:07:40 +08:00
auto bSingle = new QPushButton ( " Single " ) ;
bSingle - > setToolTip ( " Single sweep " ) ;
bSingle - > setCheckable ( true ) ;
connect ( bSingle , & QPushButton : : toggled , this , & VNA : : SetSingleSweep ) ;
connect ( this , & VNA : : singleSweepChanged , bSingle , & QPushButton : : setChecked ) ;
tb_sweep - > addWidget ( bSingle ) ;
2020-08-31 04:03:41 +08:00
auto eStart = new SIUnitEdit ( " Hz " , " kMG " , 6 ) ;
2020-11-23 19:43:24 +08:00
// calculate width required with expected string length
auto width = QFontMetrics ( eStart - > font ( ) ) . width ( " 3.00000GHz " ) + 15 ;
eStart - > setFixedWidth ( width ) ;
2020-08-31 04:03:41 +08:00
eStart - > setToolTip ( " Start frequency " ) ;
connect ( eStart , & SIUnitEdit : : valueChanged , this , & VNA : : SetStartFreq ) ;
connect ( this , & VNA : : startFreqChanged , eStart , & SIUnitEdit : : setValueQuiet ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " Start: " ) ) ) ;
frequencySweepActions . push_back ( tb_sweep - > addWidget ( eStart ) ) ;
2020-08-31 04:03:41 +08:00
auto eCenter = new SIUnitEdit ( " Hz " , " kMG " , 6 ) ;
2020-11-23 19:43:24 +08:00
eCenter - > setFixedWidth ( width ) ;
2020-08-31 04:03:41 +08:00
eCenter - > setToolTip ( " Center frequency " ) ;
connect ( eCenter , & SIUnitEdit : : valueChanged , this , & VNA : : SetCenterFreq ) ;
connect ( this , & VNA : : centerFreqChanged , eCenter , & SIUnitEdit : : setValueQuiet ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " Center: " ) ) ) ;
frequencySweepActions . push_back ( tb_sweep - > addWidget ( eCenter ) ) ;
2020-08-31 04:03:41 +08:00
auto eStop = new SIUnitEdit ( " Hz " , " kMG " , 6 ) ;
2020-11-23 19:43:24 +08:00
eStop - > setFixedWidth ( width ) ;
2020-08-31 04:03:41 +08:00
eStop - > setToolTip ( " Stop frequency " ) ;
connect ( eStop , & SIUnitEdit : : valueChanged , this , & VNA : : SetStopFreq ) ;
connect ( this , & VNA : : stopFreqChanged , eStop , & SIUnitEdit : : setValueQuiet ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " Stop: " ) ) ) ;
frequencySweepActions . push_back ( tb_sweep - > addWidget ( eStop ) ) ;
2020-08-31 04:03:41 +08:00
auto eSpan = new SIUnitEdit ( " Hz " , " kMG " , 6 ) ;
2020-11-23 19:43:24 +08:00
eSpan - > setFixedWidth ( width ) ;
2020-08-31 04:03:41 +08:00
eSpan - > setToolTip ( " Span " ) ;
connect ( eSpan , & SIUnitEdit : : valueChanged , this , & VNA : : SetSpan ) ;
connect ( this , & VNA : : spanChanged , eSpan , & SIUnitEdit : : setValueQuiet ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " Span: " ) ) ) ;
frequencySweepActions . push_back ( tb_sweep - > addWidget ( eSpan ) ) ;
2020-08-31 04:03:41 +08:00
2020-10-25 06:12:46 +08:00
auto bFull = new QPushButton ( QIcon : : fromTheme ( " zoom-fit-best " , QIcon ( " :/icons/zoom-fit.png " ) ) , " " ) ;
2020-08-31 04:03:41 +08:00
bFull - > setToolTip ( " Full span " ) ;
connect ( bFull , & QPushButton : : clicked , this , & VNA : : SetFullSpan ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( bFull ) ) ;
2020-08-31 04:03:41 +08:00
2020-10-25 06:12:46 +08:00
auto bZoomIn = new QPushButton ( QIcon : : fromTheme ( " zoom-in " , QIcon ( " :/icons/zoom-in.png " ) ) , " " ) ;
2020-08-31 04:03:41 +08:00
bZoomIn - > setToolTip ( " Zoom in " ) ;
connect ( bZoomIn , & QPushButton : : clicked , this , & VNA : : SpanZoomIn ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( bZoomIn ) ) ;
2020-08-31 04:03:41 +08:00
2020-10-25 06:12:46 +08:00
auto bZoomOut = new QPushButton ( QIcon : : fromTheme ( " zoom-out " , QIcon ( " :/icons/zoom-out.png " ) ) , " " ) ;
2020-08-31 04:03:41 +08:00
bZoomOut - > setToolTip ( " Zoom out " ) ;
connect ( bZoomOut , & QPushButton : : clicked , this , & VNA : : SpanZoomOut ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( bZoomOut ) ) ;
2022-06-27 01:32:51 +08:00
auto bZero = new QPushButton ( " 0 " ) ;
bZero - > setToolTip ( " Zero span " ) ;
bZero - > setMaximumWidth ( 28 ) ;
bZero - > setMaximumHeight ( 24 ) ;
connect ( bZero , & QPushButton : : clicked , this , & VNA : : SetZeroSpan ) ;
frequencySweepActions . push_back ( tb_sweep - > addWidget ( bZero ) ) ;
2022-01-05 23:01:51 +08:00
auto cbLogSweep = new QCheckBox ( " Log " ) ;
cbLogSweep - > setToolTip ( " Logarithmic sweep " ) ;
connect ( cbLogSweep , & QCheckBox : : toggled , this , & VNA : : SetLogSweep ) ;
connect ( this , & VNA : : logSweepChanged , cbLogSweep , & QCheckBox : : setChecked ) ;
frequencySweepActions . push_back ( tb_sweep - > addWidget ( cbLogSweep ) ) ;
2021-07-10 00:42:22 +08:00
// power sweep widgets
auto sbPowerLow = new QDoubleSpinBox ( ) ;
width = QFontMetrics ( sbPowerLow - > font ( ) ) . width ( " -30.00dBm " ) + 20 ;
sbPowerLow - > setFixedWidth ( width ) ;
sbPowerLow - > setRange ( - 100.0 , 100.0 ) ;
sbPowerLow - > setSingleStep ( 0.25 ) ;
sbPowerLow - > setSuffix ( " dbm " ) ;
sbPowerLow - > setToolTip ( " Stimulus level " ) ;
sbPowerLow - > setKeyboardTracking ( false ) ;
2021-07-10 04:26:44 +08:00
connect ( sbPowerLow , qOverload < double > ( & QDoubleSpinBox : : valueChanged ) , this , & VNA : : SetStartPower ) ;
connect ( this , & VNA : : startPowerChanged , sbPowerLow , & QDoubleSpinBox : : setValue ) ;
2021-07-10 00:42:22 +08:00
powerSweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " From: " ) ) ) ;
powerSweepActions . push_back ( tb_sweep - > addWidget ( sbPowerLow ) ) ;
auto sbPowerHigh = new QDoubleSpinBox ( ) ;
width = QFontMetrics ( sbPowerHigh - > font ( ) ) . width ( " -30.00dBm " ) + 20 ;
sbPowerHigh - > setFixedWidth ( width ) ;
sbPowerHigh - > setRange ( - 100.0 , 100.0 ) ;
sbPowerHigh - > setSingleStep ( 0.25 ) ;
sbPowerHigh - > setSuffix ( " dbm " ) ;
sbPowerHigh - > setToolTip ( " Stimulus level " ) ;
sbPowerHigh - > setKeyboardTracking ( false ) ;
2021-07-10 04:26:44 +08:00
connect ( sbPowerHigh , qOverload < double > ( & QDoubleSpinBox : : valueChanged ) , this , & VNA : : SetStopPower ) ;
connect ( this , & VNA : : stopPowerChanged , sbPowerHigh , & QDoubleSpinBox : : setValue ) ;
2021-07-10 00:42:22 +08:00
powerSweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " To: " ) ) ) ;
powerSweepActions . push_back ( tb_sweep - > addWidget ( sbPowerHigh ) ) ;
auto ePowerFreq = new SIUnitEdit ( " Hz " , " kMG " , 6 ) ;
width = QFontMetrics ( ePowerFreq - > font ( ) ) . width ( " 3.00000GHz " ) + 15 ;
ePowerFreq - > setFixedWidth ( width ) ;
ePowerFreq - > setToolTip ( " Start frequency " ) ;
2021-07-10 04:26:44 +08:00
connect ( ePowerFreq , & SIUnitEdit : : valueChanged , this , & VNA : : SetPowerSweepFrequency ) ;
connect ( this , & VNA : : powerSweepFrequencyChanged , ePowerFreq , & SIUnitEdit : : setValueQuiet ) ;
2021-07-10 00:42:22 +08:00
powerSweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " at: " ) ) ) ;
powerSweepActions . push_back ( tb_sweep - > addWidget ( ePowerFreq ) ) ;
2020-08-31 04:03:41 +08:00
2020-09-13 20:44:45 +08:00
window - > addToolBar ( tb_sweep ) ;
toolbars . insert ( tb_sweep ) ;
2020-08-31 04:03:41 +08:00
// Acquisition toolbar
2020-09-13 20:44:45 +08:00
auto tb_acq = new QToolBar ( " Acquisition " ) ;
2020-08-31 04:03:41 +08:00
auto dbm = new QDoubleSpinBox ( ) ;
2020-11-23 19:43:24 +08:00
width = QFontMetrics ( dbm - > font ( ) ) . width ( " -30.00dBm " ) + 20 ;
dbm - > setFixedWidth ( width ) ;
2020-09-30 05:03:20 +08:00
dbm - > setRange ( - 100.0 , 100.0 ) ;
2020-08-31 04:03:41 +08:00
dbm - > setSingleStep ( 0.25 ) ;
dbm - > setSuffix ( " dbm " ) ;
dbm - > setToolTip ( " Stimulus level " ) ;
2020-11-13 01:56:39 +08:00
dbm - > setKeyboardTracking ( false ) ;
2020-08-31 04:03:41 +08:00
connect ( dbm , qOverload < double > ( & QDoubleSpinBox : : valueChanged ) , this , & VNA : : SetSourceLevel ) ;
connect ( this , & VNA : : sourceLevelChanged , dbm , & QDoubleSpinBox : : setValue ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_acq - > addWidget ( new QLabel ( " Level: " ) ) ) ;
frequencySweepActions . push_back ( tb_acq - > addWidget ( dbm ) ) ;
2020-08-31 04:03:41 +08:00
auto points = new QSpinBox ( ) ;
2022-03-07 06:01:11 +08:00
points - > setFixedWidth ( 65 ) ;
points - > setRange ( 1 , UINT16_MAX ) ;
2020-08-31 04:03:41 +08:00
points - > setSingleStep ( 100 ) ;
points - > setToolTip ( " Points/sweep " ) ;
2020-11-13 01:56:39 +08:00
points - > setKeyboardTracking ( false ) ;
2020-08-31 04:03:41 +08:00
connect ( points , qOverload < int > ( & QSpinBox : : valueChanged ) , this , & VNA : : SetPoints ) ;
2020-11-07 20:22:10 +08:00
connect ( this , & VNA : : pointsChanged , [ = ] ( int p ) {
points - > blockSignals ( true ) ;
points - > setValue ( p ) ;
points - > blockSignals ( false ) ;
} ) ;
2020-08-31 04:03:41 +08:00
tb_acq - > addWidget ( new QLabel ( " Points: " ) ) ;
tb_acq - > addWidget ( points ) ;
auto eBandwidth = new SIUnitEdit ( " Hz " , " k " , 3 ) ;
eBandwidth - > setFixedWidth ( 70 ) ;
eBandwidth - > setToolTip ( " IF bandwidth " ) ;
connect ( eBandwidth , & SIUnitEdit : : valueChanged , this , & VNA : : SetIFBandwidth ) ;
connect ( this , & VNA : : IFBandwidthChanged , eBandwidth , & SIUnitEdit : : setValueQuiet ) ;
tb_acq - > addWidget ( new QLabel ( " IF BW: " ) ) ;
tb_acq - > addWidget ( eBandwidth ) ;
2020-10-23 17:39:07 +08:00
tb_acq - > addWidget ( new QLabel ( " Averaging: " ) ) ;
lAverages = new QLabel ( " 0/ " ) ;
tb_acq - > addWidget ( lAverages ) ;
auto sbAverages = new QSpinBox ;
sbAverages - > setRange ( 1 , 99 ) ;
sbAverages - > setFixedWidth ( 40 ) ;
connect ( sbAverages , qOverload < int > ( & QSpinBox : : valueChanged ) , this , & VNA : : SetAveraging ) ;
connect ( this , & VNA : : averagingChanged , sbAverages , & QSpinBox : : setValue ) ;
tb_acq - > addWidget ( sbAverages ) ;
2020-09-13 20:44:45 +08:00
window - > addToolBar ( tb_acq ) ;
toolbars . insert ( tb_acq ) ;
2020-08-31 04:03:41 +08:00
// Calibration toolbar (and populate calibration menu)
auto tb_cal = new QToolBar ( " Calibration " ) ;
2020-12-08 00:58:13 +08:00
calLabel = new QLabel ( " Calibration: " ) ;
UpdateCalWidget ( ) ;
tb_cal - > addWidget ( calLabel ) ;
2020-08-31 04:03:41 +08:00
auto cbEnableCal = new QCheckBox ;
tb_cal - > addWidget ( cbEnableCal ) ;
auto cbType = new QComboBox ( ) ;
2022-08-30 02:07:07 +08:00
auto updateCalComboBox = [ = ] ( ) {
auto cals = cal . getAvailableCalibrations ( ) ;
cbType - > blockSignals ( true ) ;
cbType - > clear ( ) ;
for ( auto c : cals ) {
if ( c . type = = Calibration : : Type : : None ) {
continue ;
}
cbType - > addItem ( c . getShortString ( ) ) ;
}
cbType - > setCurrentText ( cal . getCaltype ( ) . getShortString ( ) ) ;
cbType - > blockSignals ( false ) ;
} ;
connect ( this , & VNA : : deviceInitialized , updateCalComboBox ) ;
updateCalComboBox ( ) ;
2020-08-31 04:03:41 +08:00
auto calToolbarLambda = [ = ] ( ) {
if ( cbEnableCal - > isChecked ( ) ) {
// Get requested calibration type from combobox
2022-08-30 02:07:07 +08:00
ApplyCalibration ( Calibration : : CalType : : fromShortString ( cbType - > currentText ( ) ) ) ;
2020-08-31 04:03:41 +08:00
} else {
DisableCalibration ( ) ;
}
} ;
// Calibration connections
2022-08-30 02:07:07 +08:00
connect ( & cal , & Calibration : : activated , this , & VNA : : UpdateStatusbar ) ;
connect ( & cal , & Calibration : : deactivated , this , & VNA : : UpdateStatusbar ) ;
2020-08-31 04:03:41 +08:00
connect ( cbEnableCal , & QCheckBox : : stateChanged , calToolbarLambda ) ;
connect ( cbType , qOverload < int > ( & QComboBox : : currentIndexChanged ) , calToolbarLambda ) ;
2022-08-30 02:07:07 +08:00
connect ( & cal , & Calibration : : deactivated , [ = ] ( ) {
2020-08-31 04:03:41 +08:00
cbType - > blockSignals ( true ) ;
cbEnableCal - > blockSignals ( true ) ;
cbEnableCal - > setCheckState ( Qt : : CheckState : : Unchecked ) ;
2020-12-08 00:58:13 +08:00
// visually indicate loss of calibration
// cal. file unknown at this moment
UpdateCalWidget ( ) ;
2020-08-31 04:03:41 +08:00
cbType - > blockSignals ( false ) ;
cbEnableCal - > blockSignals ( false ) ;
2020-11-28 01:18:31 +08:00
calImportTerms - > setEnabled ( false ) ;
calImportMeas - > setEnabled ( false ) ;
2021-03-12 04:52:58 +08:00
calApplyToTraces - > setEnabled ( false ) ;
2020-11-11 02:16:16 +08:00
saveCal - > setEnabled ( false ) ;
2020-08-31 04:03:41 +08:00
} ) ;
2022-08-30 02:07:07 +08:00
connect ( & cal , & Calibration : : activated , [ = ] ( Calibration : : CalType applied ) {
2020-08-31 04:03:41 +08:00
cbType - > blockSignals ( true ) ;
cbEnableCal - > blockSignals ( true ) ;
2022-08-30 02:07:07 +08:00
cbType - > setCurrentText ( applied . getShortString ( ) ) ;
2020-08-31 04:03:41 +08:00
cbEnableCal - > setCheckState ( Qt : : CheckState : : Checked ) ;
2020-12-08 00:58:13 +08:00
// restore default look of widget
// on hover, show name of active cal. file
UpdateCalWidget ( ) ;
2020-08-31 04:03:41 +08:00
cbType - > blockSignals ( false ) ;
cbEnableCal - > blockSignals ( false ) ;
2020-11-28 01:18:31 +08:00
calImportTerms - > setEnabled ( true ) ;
calImportMeas - > setEnabled ( true ) ;
2021-03-12 04:52:58 +08:00
calApplyToTraces - > setEnabled ( true ) ;
2020-11-11 02:16:16 +08:00
saveCal - > setEnabled ( true ) ;
2020-08-31 04:03:41 +08:00
} ) ;
tb_cal - > addWidget ( cbType ) ;
2020-09-13 20:44:45 +08:00
window - > addToolBar ( tb_cal ) ;
2021-07-10 04:26:44 +08:00
auto configureToolbarForFrequencySweep = [ = ] ( ) {
for ( auto a : frequencySweepActions ) {
a - > setVisible ( true ) ;
}
for ( auto a : powerSweepActions ) {
a - > setVisible ( false ) ;
}
// enable calibration menu entries
calData - > setEnabled ( true ) ;
} ;
auto configureToolbarForPowerSweep = [ = ] ( ) {
for ( auto a : frequencySweepActions ) {
a - > setVisible ( false ) ;
}
for ( auto a : powerSweepActions ) {
a - > setVisible ( true ) ;
}
// disable calibration menu entries
calData - > setEnabled ( false ) ;
} ;
connect ( cbSweepType , qOverload < int > ( & QComboBox : : currentIndexChanged ) , [ = ] ( int index ) {
SetSweepType ( ( SweepType ) index ) ;
} ) ;
connect ( this , & VNA : : sweepTypeChanged , [ = ] ( SweepType sw ) {
if ( sw = = SweepType : : Frequency ) {
configureToolbarForFrequencySweep ( ) ;
} else if ( sw = = SweepType : : Power ) {
configureToolbarForPowerSweep ( ) ;
}
2021-07-10 20:04:05 +08:00
cbSweepType - > setCurrentIndex ( ( int ) sw ) ;
2021-07-10 04:26:44 +08:00
} ) ;
2021-10-11 21:22:08 +08:00
configureToolbarForFrequencySweep ( ) ;
2021-07-10 04:26:44 +08:00
// initial setup is frequency sweep
2021-07-15 03:47:43 +08:00
configureToolbarForFrequencySweep ( ) ;
2021-07-10 04:26:44 +08:00
SetSweepType ( SweepType : : Frequency ) ;
2020-09-13 20:44:45 +08:00
toolbars . insert ( tb_cal ) ;
2021-06-19 21:33:43 +08:00
markerModel = new MarkerModel ( traceModel , this ) ;
2020-09-13 20:44:45 +08:00
auto tracesDock = new QDockWidget ( " Traces " ) ;
2021-04-13 01:48:19 +08:00
traceWidget = new TraceWidgetVNA ( traceModel , cal , deembedding ) ;
tracesDock - > setWidget ( traceWidget ) ;
2020-09-13 20:44:45 +08:00
window - > addDockWidget ( Qt : : LeftDockWidgetArea , tracesDock ) ;
docks . insert ( tracesDock ) ;
auto markerWidget = new MarkerWidget ( * markerModel ) ;
auto markerDock = new QDockWidget ( " Marker " ) ;
markerDock - > setWidget ( markerWidget ) ;
window - > addDockWidget ( Qt : : BottomDockWidgetArea , markerDock ) ;
docks . insert ( markerDock ) ;
2021-04-13 01:48:19 +08:00
SetupSCPI ( ) ;
2020-09-13 20:44:45 +08:00
// Set initial sweep settings
2020-10-23 03:12:33 +08:00
auto pref = Preferences : : getInstance ( ) ;
2021-07-10 04:26:44 +08:00
2021-12-02 05:11:50 +08:00
if ( pref . Acquisition . useMedianAveraging ) {
average . setMode ( Averaging : : Mode : : Median ) ;
} else {
average . setMode ( Averaging : : Mode : : Mean ) ;
}
2020-09-13 20:44:45 +08:00
if ( pref . Startup . RememberSweepSettings ) {
LoadSweepSettings ( ) ;
} else {
2021-07-10 04:26:44 +08:00
settings . Freq . start = pref . Startup . DefaultSweep . f_start ;
settings . Freq . stop = pref . Startup . DefaultSweep . f_stop ;
2022-01-08 07:49:00 +08:00
SetLogSweep ( pref . Startup . DefaultSweep . logSweep ) ;
2021-07-10 04:26:44 +08:00
SetSourceLevel ( pref . Startup . DefaultSweep . f_excitation ) ;
2020-09-13 20:44:45 +08:00
ConstrainAndUpdateFrequencies ( ) ;
2021-07-10 04:26:44 +08:00
SetStartPower ( pref . Startup . DefaultSweep . dbm_start ) ;
SetStopPower ( pref . Startup . DefaultSweep . dbm_stop ) ;
SetPowerSweepFrequency ( pref . Startup . DefaultSweep . dbm_freq ) ;
2020-09-13 20:44:45 +08:00
SetIFBandwidth ( pref . Startup . DefaultSweep . bandwidth ) ;
2020-10-23 17:39:07 +08:00
SetAveraging ( pref . Startup . DefaultSweep . averaging ) ;
2020-09-13 20:44:45 +08:00
SetPoints ( pref . Startup . DefaultSweep . points ) ;
2021-07-10 20:04:05 +08:00
if ( pref . Startup . DefaultSweep . type = = " Power Sweep " ) {
SetSweepType ( SweepType : : Power ) ;
2021-12-11 03:46:04 +08:00
} else {
SetSweepType ( SweepType : : Frequency ) ;
2021-07-10 20:04:05 +08:00
}
2020-09-13 20:44:45 +08:00
}
2020-09-17 21:51:20 +08:00
// Set ObjectName for toolbars and docks
for ( auto d : findChildren < QDockWidget * > ( ) ) {
d - > setObjectName ( d - > windowTitle ( ) ) ;
}
for ( auto t : findChildren < QToolBar * > ( ) ) {
t - > setObjectName ( t - > windowTitle ( ) ) ;
}
finalize ( central ) ;
2020-09-13 20:44:45 +08:00
}
2021-07-10 04:26:44 +08:00
Calibration : : InterpolationType VNA : : getCalInterpolation ( )
{
double f_min , f_max ;
switch ( settings . sweepType ) {
2021-09-04 01:01:22 +08:00
case SweepType : : Last :
// should never get here, use frequency values just in case
2021-07-10 04:26:44 +08:00
case SweepType : : Frequency :
f_min = settings . Freq . start ;
f_max = settings . Freq . stop ;
break ;
case SweepType : : Power :
f_min = settings . Power . frequency ;
f_max = settings . Power . frequency ;
break ;
}
return cal . getInterpolation ( f_min , f_max , settings . npoints ) ;
}
2020-12-07 23:04:59 +08:00
QString VNA : : getCalStyle ( )
2020-12-07 11:18:01 +08:00
{
2022-08-30 02:07:07 +08:00
auto interpol = getCalInterpolation ( ) ;
2020-12-07 11:18:01 +08:00
QString style = " " ;
switch ( interpol )
{
case Calibration : : InterpolationType : : Unchanged :
case Calibration : : InterpolationType : : Exact :
case Calibration : : InterpolationType : : Interpolate :
style = " " ;
break ;
case Calibration : : InterpolationType : : Extrapolate :
style = " background-color: yellow " ;
break ;
case Calibration : : InterpolationType : : NoCalibration :
style = " background-color: red " ;
break ;
}
return style ;
}
QString VNA : : getCalToolTip ( )
{
2022-08-30 02:07:07 +08:00
auto interpol = getCalInterpolation ( ) ;
2020-12-07 11:18:01 +08:00
QString txt = " " ;
switch ( interpol )
{
case Calibration : : InterpolationType : : Unchanged :
case Calibration : : InterpolationType : : Exact :
case Calibration : : InterpolationType : : Interpolate :
case Calibration : : InterpolationType : : Extrapolate :
2020-12-07 23:04:59 +08:00
{
QString lo = Unit : : ToString ( cal . getMinFreq ( ) , " " , " kMG " , 5 ) ;
QString hi = Unit : : ToString ( cal . getMaxFreq ( ) , " " , " kMG " , 5 ) ;
2021-07-10 04:26:44 +08:00
if ( settings . Freq . start < cal . getMinFreq ( ) ) { lo = " <font color= \" red \" > " + lo + " </font> " ; }
if ( settings . Freq . stop > cal . getMaxFreq ( ) ) { hi = " <font color= \" red \" > " + hi + " </font> " ; }
2020-12-07 23:04:59 +08:00
txt =
" limits: " + lo + " - " + hi
+ " <br> "
+ " points: " + QString : : number ( cal . getNumPoints ( ) )
+ " <br> "
" file: " + cal . getCurrentCalibrationFile ( ) ;
2020-12-07 11:18:01 +08:00
break ;
2020-12-07 23:04:59 +08:00
}
2020-12-07 11:18:01 +08:00
case Calibration : : InterpolationType : : NoCalibration :
txt = " none " ;
break ;
}
return txt ;
}
2020-12-07 09:44:25 +08:00
2020-09-13 20:44:45 +08:00
void VNA : : deactivate ( )
{
StoreSweepSettings ( ) ;
Mode : : deactivate ( ) ;
}
void VNA : : initializeDevice ( )
{
2020-09-14 00:01:32 +08:00
defaultCalMenu - > setEnabled ( true ) ;
2022-08-05 18:20:41 +08:00
connect ( window - > getDevice ( ) , & VirtualDevice : : VNAmeasurementReceived , this , & VNA : : NewDatapoint , Qt : : UniqueConnection ) ;
2020-09-13 20:44:45 +08:00
// Check if default calibration exists and attempt to load it
QSettings s ;
auto key = " DefaultCalibration " + window - > getDevice ( ) - > serial ( ) ;
if ( s . contains ( key ) ) {
auto filename = s . value ( key ) . toString ( ) ;
2020-11-12 02:13:53 +08:00
qDebug ( ) < < " Attempting to load default calibration file " < < filename ;
2020-09-13 20:44:45 +08:00
if ( QFile : : exists ( filename ) ) {
2022-08-30 02:07:07 +08:00
if ( cal . fromFile ( filename ) ) {
2020-12-01 00:05:15 +08:00
qDebug ( ) < < " Calibration successful from " < < filename ;
} else {
qDebug ( ) < < " Calibration not successfull from: " < < filename ;
2020-11-11 02:16:16 +08:00
}
2020-12-01 00:05:15 +08:00
} else {
qDebug ( ) < < " Calibration file not found: " < < filename ;
2020-09-13 20:44:45 +08:00
}
2020-09-14 00:01:32 +08:00
removeDefaultCal - > setEnabled ( true ) ;
2020-09-13 20:44:45 +08:00
} else {
qDebug ( ) < < " No default calibration file set for this device " ;
2020-09-14 00:01:32 +08:00
removeDefaultCal - > setEnabled ( false ) ;
2020-09-13 20:44:45 +08:00
}
// Configure initial state of device
2020-09-20 16:13:06 +08:00
SettingsChanged ( ) ;
2022-08-30 02:07:07 +08:00
emit deviceInitialized ( ) ;
2020-08-31 04:03:41 +08:00
}
2020-09-14 00:01:32 +08:00
void VNA : : deviceDisconnected ( )
{
defaultCalMenu - > setEnabled ( false ) ;
}
2020-12-08 03:21:24 +08:00
void VNA : : shutdown ( )
{
2022-10-01 08:31:42 +08:00
if ( cal . hasUnsavedChanges ( ) & & cal . getCaltype ( ) . type ! = Calibration : : Type : : None ) {
2020-12-08 03:21:24 +08:00
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 ) {
2022-08-30 02:07:07 +08:00
cal . toFile ( ) ;
2020-12-08 03:21:24 +08:00
}
}
}
2020-12-05 06:49:52 +08:00
nlohmann : : json VNA : : toJSON ( )
{
nlohmann : : json j ;
2021-09-04 01:01:22 +08:00
// save current sweep/acquisition settings
nlohmann : : json sweep ;
sweep [ " type " ] = SweepTypeToString ( settings . sweepType ) . toStdString ( ) ;
nlohmann : : json freq ;
freq [ " start " ] = settings . Freq . start ;
freq [ " stop " ] = settings . Freq . stop ;
freq [ " power " ] = settings . Freq . excitation_power ;
2022-01-05 23:01:51 +08:00
freq [ " log " ] = settings . Freq . logSweep ;
2021-09-04 01:01:22 +08:00
sweep [ " frequency " ] = freq ;
2022-05-18 02:07:40 +08:00
sweep [ " single " ] = singleSweep ;
2021-09-04 01:01:22 +08:00
nlohmann : : json power ;
power [ " start " ] = settings . Power . start ;
power [ " stop " ] = settings . Power . stop ;
power [ " frequency " ] = settings . Power . frequency ;
sweep [ " power " ] = power ;
sweep [ " points " ] = settings . npoints ;
sweep [ " IFBW " ] = settings . bandwidth ;
j [ " sweep " ] = sweep ;
2020-12-05 06:49:52 +08:00
j [ " traces " ] = traceModel . toJSON ( ) ;
j [ " tiles " ] = central - > toJSON ( ) ;
2020-12-05 19:59:23 +08:00
j [ " markers " ] = markerModel - > toJSON ( ) ;
2021-01-30 04:44:44 +08:00
j [ " de-embedding " ] = deembedding . toJSON ( ) ;
2021-03-12 04:52:58 +08:00
j [ " de-embedding_enabled " ] = deembedding_active ;
2020-12-05 06:49:52 +08:00
return j ;
}
void VNA : : fromJSON ( nlohmann : : json j )
{
2021-09-04 01:01:22 +08:00
if ( j . is_null ( ) ) {
return ;
}
2020-12-05 06:49:52 +08:00
if ( j . contains ( " traces " ) ) {
traceModel . fromJSON ( j [ " traces " ] ) ;
}
if ( j . contains ( " tiles " ) ) {
central - > fromJSON ( j [ " tiles " ] ) ;
}
2020-12-05 19:59:23 +08:00
if ( j . contains ( " markers " ) ) {
markerModel - > fromJSON ( j [ " markers " ] ) ;
}
2021-01-30 04:44:44 +08:00
if ( j . contains ( " de-embedding " ) ) {
deembedding . fromJSON ( j [ " de-embedding " ] ) ;
2021-03-12 04:52:58 +08:00
EnableDeembedding ( j . value ( " de-embedding_enabled " , true ) ) ;
} else {
EnableDeembedding ( false ) ;
2021-01-30 04:44:44 +08:00
}
2021-09-04 01:01:22 +08:00
2022-03-17 19:53:13 +08:00
// sweep configuration has to go last so graphs can catch events from changed sweep
2021-09-04 01:01:22 +08:00
if ( j . contains ( " sweep " ) ) {
auto sweep = j [ " sweep " ] ;
// restore sweep settings, keep current value as default in case of missing entry
SetPoints ( sweep . value ( " points " , settings . npoints ) ) ;
SetIFBandwidth ( sweep . value ( " IFBW " , settings . bandwidth ) ) ;
if ( sweep . contains ( " frequency " ) ) {
auto freq = sweep [ " frequency " ] ;
SetStartFreq ( freq . value ( " start " , settings . Freq . start ) ) ;
SetStopFreq ( freq . value ( " stop " , settings . Freq . stop ) ) ;
SetSourceLevel ( freq . value ( " power " , settings . Freq . excitation_power ) ) ;
2022-01-05 23:01:51 +08:00
SetLogSweep ( freq . value ( " log " , settings . Freq . logSweep ) ) ;
2021-09-04 01:01:22 +08:00
}
if ( sweep . contains ( " power " ) ) {
auto power = sweep [ " power " ] ;
SetStartPower ( power . value ( " start " , settings . Power . start ) ) ;
SetStopPower ( power . value ( " stop " , settings . Power . stop ) ) ;
SetPowerSweepFrequency ( power . value ( " frequency " , settings . Power . frequency ) ) ;
}
auto type = SweepTypeFromString ( QString : : fromStdString ( sweep [ " type " ] ) ) ;
if ( type = = SweepType : : Last ) {
// default to frequency sweep
type = SweepType : : Frequency ;
}
SetSweepType ( type ) ;
2022-05-18 02:07:40 +08:00
SetSingleSweep ( sweep . value ( " single " , singleSweep ) ) ;
2021-09-04 01:01:22 +08:00
}
2020-12-05 06:49:52 +08:00
}
2020-09-13 20:44:45 +08:00
using namespace std ;
2022-08-05 18:20:41 +08:00
void VNA : : NewDatapoint ( VirtualDevice : : VNAMeasurement m )
2020-08-31 04:03:41 +08:00
{
2022-07-14 21:25:33 +08:00
if ( isActive ! = true ) {
2022-04-04 05:34:18 +08:00
// ignore
return ;
}
2022-03-08 05:51:56 +08:00
if ( changingSettings ) {
// already setting new sweep settings, ignore incoming points from old settings
return ;
}
2022-05-18 02:07:40 +08:00
if ( singleSweep & & average . getLevel ( ) = = averages ) {
changingSettings = true ;
// single sweep finished
2022-08-05 18:20:41 +08:00
window - > getDevice ( ) - > setIdle ( [ = ] ( bool ) {
2022-05-18 02:07:40 +08:00
changingSettings = false ;
} ) ;
}
2022-08-05 18:20:41 +08:00
auto m_avg = m ;
2022-03-07 06:01:11 +08:00
bool needsSegmentUpdate = false ;
if ( settings . segments > 1 ) {
// using multiple segments, adjust pointNum
auto pointsPerSegment = ceil ( ( double ) settings . npoints / settings . segments ) ;
2022-08-05 18:20:41 +08:00
if ( m_avg . pointNum = = pointsPerSegment - 1 ) {
2022-03-07 06:01:11 +08:00
needsSegmentUpdate = true ;
}
2022-08-05 18:20:41 +08:00
m_avg . pointNum + = pointsPerSegment * settings . activeSegment ;
if ( m_avg . pointNum = = settings . npoints - 1 ) {
2022-03-07 06:01:11 +08:00
needsSegmentUpdate = true ;
}
}
2022-08-05 18:20:41 +08:00
if ( m_avg . pointNum > = settings . npoints ) {
qWarning ( ) < < " Ignoring point with too large point number ( " < < m . pointNum < < " ) " ;
2021-11-14 02:26:27 +08:00
return ;
}
2022-08-05 18:20:41 +08:00
m_avg = average . process ( m_avg ) ;
2022-06-23 05:00:09 +08:00
2020-09-13 20:44:45 +08:00
if ( calMeasuring ) {
2020-10-30 02:27:04 +08:00
if ( average . currentSweep ( ) = = averages ) {
// this is the last averaging sweep, use values for calibration
2022-08-05 18:20:41 +08:00
if ( ! calWaitFirst | | m_avg . pointNum = = 0 ) {
2020-10-30 02:27:04 +08:00
calWaitFirst = false ;
2022-08-30 02:07:07 +08:00
cal . addMeasurements ( calMeasurements , m_avg ) ;
2022-08-05 18:20:41 +08:00
if ( m_avg . pointNum = = settings . npoints - 1 ) {
2020-10-30 02:27:04 +08:00
calMeasuring = false ;
2022-08-30 02:07:07 +08:00
cal . measurementsComplete ( ) ;
2020-10-30 02:27:04 +08:00
}
2020-08-31 04:03:41 +08:00
}
2020-09-13 20:44:45 +08:00
}
2022-08-05 18:20:41 +08:00
int percentage = ( ( ( average . currentSweep ( ) - 1 ) * 100 ) + ( m_avg . pointNum + 1 ) * 100 / settings . npoints ) / averages ;
2020-10-30 02:27:04 +08:00
calDialog . setValue ( percentage ) ;
2020-09-13 20:44:45 +08:00
}
2022-08-30 02:07:07 +08:00
cal . correctMeasurement ( m_avg ) ;
2021-01-30 04:44:44 +08:00
2021-03-12 04:52:58 +08:00
if ( deembedding_active ) {
2022-08-05 18:20:41 +08:00
deembedding . Deembed ( m_avg ) ;
2021-03-12 04:52:58 +08:00
}
2020-10-31 23:52:59 +08:00
2021-07-10 04:26:44 +08:00
TraceMath : : DataType type ;
2022-06-20 07:02:09 +08:00
if ( settings . zerospan ) {
type = TraceMath : : DataType : : TimeZeroSpan ;
// keep track of first point time
2022-08-05 18:20:41 +08:00
if ( m_avg . pointNum = = 0 ) {
settings . firstPointTime = m_avg . us ;
m_avg . us = 0 ;
2022-06-20 07:02:09 +08:00
} else {
2022-08-05 18:20:41 +08:00
m_avg . us - = settings . firstPointTime ;
2022-06-20 07:02:09 +08:00
}
} else {
switch ( settings . sweepType ) {
case SweepType : : Last :
case SweepType : : Frequency :
type = TraceMath : : DataType : : Frequency ;
break ;
case SweepType : : Power :
type = TraceMath : : DataType : : Power ;
break ;
}
2021-07-10 04:26:44 +08:00
}
2022-08-05 18:20:41 +08:00
traceModel . addVNAData ( m_avg , type ) ;
2020-09-13 20:44:45 +08:00
emit dataChanged ( ) ;
2022-08-05 18:20:41 +08:00
if ( m_avg . pointNum = = settings . npoints - 1 ) {
2020-10-23 17:39:07 +08:00
UpdateAverageCount ( ) ;
2020-10-20 23:03:49 +08:00
markerModel - > updateMarkers ( ) ;
2020-09-13 20:44:45 +08:00
}
2020-11-24 23:28:57 +08:00
static unsigned int lastPoint = 0 ;
2022-08-05 18:20:41 +08:00
if ( m_avg . pointNum > 0 & & m_avg . pointNum ! = lastPoint + 1 ) {
qWarning ( ) < < " Got point " < < m_avg . pointNum < < " but last received point was " < < lastPoint < < " ( " < < ( m_avg . pointNum - lastPoint - 1 ) < < " missed points) " ;
2020-11-24 23:28:57 +08:00
}
2022-08-05 18:20:41 +08:00
lastPoint = m_avg . pointNum ;
2022-03-07 06:01:11 +08:00
if ( needsSegmentUpdate ) {
2022-03-08 05:51:56 +08:00
changingSettings = true ;
2022-03-07 06:01:11 +08:00
if ( settings . activeSegment < settings . segments - 1 ) {
settings . activeSegment + + ;
} else {
settings . activeSegment = 0 ;
}
SettingsChanged ( false ) ;
}
2020-09-13 20:44:45 +08:00
}
2020-10-23 17:39:07 +08:00
void VNA : : UpdateAverageCount ( )
2020-09-13 20:44:45 +08:00
{
2020-10-23 17:39:07 +08:00
lAverages - > setText ( QString : : number ( average . getLevel ( ) ) + " / " ) ;
2020-08-31 04:03:41 +08:00
}
2022-08-05 18:20:41 +08:00
void VNA : : SettingsChanged ( bool resetTraces , std : : function < void ( bool ) > cb )
2020-08-31 04:03:41 +08:00
{
2022-03-08 05:51:56 +08:00
if ( resetTraces ) {
settings . activeSegment = 0 ;
}
changingSettings = true ;
2021-07-10 04:26:44 +08:00
// assemble VNA protocol settings
2022-08-05 18:20:41 +08:00
VirtualDevice : : VNASettings s = { } ;
s . IFBW = settings . bandwidth ;
2022-08-09 00:08:40 +08:00
if ( Preferences : : getInstance ( ) . Acquisition . alwaysExciteAllPorts ) {
2022-08-06 22:22:12 +08:00
for ( int i = 0 ; i < VirtualDevice : : getInfo ( window - > getDevice ( ) ) . ports ; i + + ) {
2022-08-05 18:20:41 +08:00
s . excitedPorts . push_back ( i ) ;
}
2021-07-10 04:26:44 +08:00
} else {
2022-08-06 22:22:12 +08:00
for ( int i = 0 ; i < VirtualDevice : : getInfo ( window - > getDevice ( ) ) . ports ; i + + ) {
2022-08-05 18:20:41 +08:00
if ( traceModel . PortExcitationRequired ( i ) )
s . excitedPorts . push_back ( i ) ;
}
2021-07-10 04:26:44 +08:00
}
2022-08-05 18:20:41 +08:00
settings . excitedPorts = s . excitedPorts ;
2022-03-07 06:01:11 +08:00
double start = settings . sweepType = = SweepType : : Frequency ? settings . Freq . start : settings . Power . start ;
double stop = settings . sweepType = = SweepType : : Frequency ? settings . Freq . stop : settings . Power . stop ;
int npoints = settings . npoints ;
emit traceModel . SpanChanged ( start , stop ) ;
if ( settings . segments > 1 ) {
// more than one segment, adjust start/stop
npoints = ceil ( ( double ) settings . npoints / settings . segments ) ;
2022-08-05 18:20:41 +08:00
unsigned int segmentStartPoint = npoints * settings . activeSegment ;
unsigned int segmentStopPoint = segmentStartPoint + npoints - 1 ;
2022-03-07 06:01:11 +08:00
if ( segmentStopPoint > = settings . npoints ) {
segmentStopPoint = settings . npoints - 1 ;
npoints = settings . npoints - segmentStartPoint ;
}
auto seg_start = Util : : Scale < double > ( segmentStartPoint , 0 , settings . npoints - 1 , start , stop ) ;
auto seg_stop = Util : : Scale < double > ( segmentStopPoint , 0 , settings . npoints - 1 , start , stop ) ;
start = seg_start ;
stop = seg_stop ;
}
2021-07-10 04:26:44 +08:00
if ( settings . sweepType = = SweepType : : Frequency ) {
2022-08-05 18:20:41 +08:00
s . freqStart = start ;
s . freqStop = stop ;
2022-03-07 06:01:11 +08:00
s . points = npoints ;
2022-08-05 18:20:41 +08:00
s . dBmStart = settings . Freq . excitation_power ;
s . dBmStop = settings . Freq . excitation_power ;
2022-01-05 23:01:51 +08:00
s . logSweep = settings . Freq . logSweep ;
2021-07-10 04:26:44 +08:00
} else if ( settings . sweepType = = SweepType : : Power ) {
2022-08-05 18:20:41 +08:00
s . freqStart = settings . Power . frequency ;
s . freqStop = settings . Power . frequency ;
2022-03-07 06:01:11 +08:00
s . points = npoints ;
2022-08-05 18:20:41 +08:00
s . dBmStart = start ;
s . dBmStop = stop ;
2022-01-05 23:01:51 +08:00
s . logSweep = false ;
2021-07-10 04:26:44 +08:00
}
2022-07-14 21:25:33 +08:00
if ( window - > getDevice ( ) & & isActive ) {
2022-08-05 18:20:41 +08:00
window - > getDevice ( ) - > setVNA ( s , [ = ] ( bool res ) {
// device received command, reset traces now
if ( resetTraces ) {
average . reset ( settings . npoints ) ;
traceModel . clearLiveData ( ) ;
UpdateAverageCount ( ) ;
UpdateCalWidget ( ) ;
}
if ( cb ) {
cb ( res ) ;
}
2022-03-08 05:51:56 +08:00
changingSettings = false ;
2022-08-05 18:20:41 +08:00
} ) ;
2020-09-13 20:44:45 +08:00
}
2020-08-31 04:03:41 +08:00
}
void VNA : : StartImpedanceMatching ( )
{
auto dialog = new ImpedanceMatchDialog ( * markerModel ) ;
2022-03-03 19:28:59 +08:00
if ( AppWindow : : showGUI ( ) ) {
dialog - > show ( ) ;
}
2020-08-31 04:03:41 +08:00
}
2021-07-10 04:26:44 +08:00
void VNA : : SetSweepType ( SweepType sw )
{
if ( settings . sweepType ! = sw ) {
settings . sweepType = sw ;
emit sweepTypeChanged ( sw ) ;
SettingsChanged ( ) ;
}
}
2020-08-31 04:03:41 +08:00
void VNA : : SetStartFreq ( double freq )
{
2021-07-10 04:26:44 +08:00
settings . Freq . start = freq ;
if ( settings . Freq . stop < freq ) {
settings . Freq . stop = freq ;
2020-08-31 04:03:41 +08:00
}
ConstrainAndUpdateFrequencies ( ) ;
}
void VNA : : SetStopFreq ( double freq )
{
2021-07-10 04:26:44 +08:00
settings . Freq . stop = freq ;
if ( settings . Freq . start > freq ) {
settings . Freq . start = freq ;
2020-08-31 04:03:41 +08:00
}
ConstrainAndUpdateFrequencies ( ) ;
}
void VNA : : SetCenterFreq ( double freq )
{
2021-07-10 04:26:44 +08:00
auto old_span = settings . Freq . stop - settings . Freq . start ;
2022-08-05 18:20:41 +08:00
if ( freq - old_span / 2 < = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . minFreq ) {
2020-11-13 01:56:39 +08:00
// would shift start frequency below minimum
2021-07-10 04:26:44 +08:00
settings . Freq . start = 0 ;
settings . Freq . stop = 2 * freq ;
2022-08-05 18:20:41 +08:00
} else if ( freq + old_span / 2 > = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxFreq ) {
2020-11-13 01:56:39 +08:00
// would shift stop frequency above maximum
2022-08-05 18:20:41 +08:00
settings . Freq . start = 2 * freq - VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxFreq ;
settings . Freq . stop = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxFreq ;
2020-11-13 01:56:39 +08:00
} else {
2021-07-10 04:26:44 +08:00
settings . Freq . start = freq - old_span / 2 ;
settings . Freq . stop = freq + old_span / 2 ;
2020-08-31 04:03:41 +08:00
}
ConstrainAndUpdateFrequencies ( ) ;
}
void VNA : : SetSpan ( double span )
{
2022-08-05 18:20:41 +08:00
auto maxFreq = Preferences : : getInstance ( ) . Acquisition . harmonicMixing ? VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxFreqHarmonic : VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxFreq ;
2021-07-10 04:26:44 +08:00
auto old_center = ( settings . Freq . start + settings . Freq . stop ) / 2 ;
2022-08-05 18:20:41 +08:00
if ( old_center < VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . minFreq + span / 2 ) {
2020-11-13 01:56:39 +08:00
// would shift start frequency below minimum
2022-08-05 18:20:41 +08:00
settings . Freq . start = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . minFreq ;
settings . Freq . stop = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . minFreq + span ;
2021-04-18 05:22:14 +08:00
} else if ( old_center > maxFreq - span / 2 ) {
2020-11-13 01:56:39 +08:00
// would shift stop frequency above maximum
2021-07-10 04:26:44 +08:00
settings . Freq . start = maxFreq - span ;
settings . Freq . stop = maxFreq ;
2020-08-31 04:03:41 +08:00
} else {
2021-07-10 04:26:44 +08:00
settings . Freq . start = old_center - span / 2 ;
settings . Freq . stop = settings . Freq . start + span ;
2020-08-31 04:03:41 +08:00
}
ConstrainAndUpdateFrequencies ( ) ;
}
void VNA : : SetFullSpan ( )
{
2022-08-05 18:20:41 +08:00
settings . Freq . start = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . minFreq ;
settings . Freq . stop = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxFreq ;
2020-08-31 04:03:41 +08:00
ConstrainAndUpdateFrequencies ( ) ;
}
2022-06-20 07:02:09 +08:00
void VNA : : SetZeroSpan ( )
{
auto center = ( settings . Freq . start + settings . Freq . stop ) / 2 ;
SetStartFreq ( center ) ;
SetStopFreq ( center ) ;
}
2020-08-31 04:03:41 +08:00
void VNA : : SpanZoomIn ( )
{
2021-07-10 04:26:44 +08:00
auto center = ( settings . Freq . start + settings . Freq . stop ) / 2 ;
auto old_span = settings . Freq . stop - settings . Freq . start ;
settings . Freq . start = center - old_span / 4 ;
settings . Freq . stop = center + old_span / 4 ;
2020-08-31 04:03:41 +08:00
ConstrainAndUpdateFrequencies ( ) ;
}
void VNA : : SpanZoomOut ( )
{
2021-07-10 04:26:44 +08:00
auto center = ( settings . Freq . start + settings . Freq . stop ) / 2 ;
auto old_span = settings . Freq . stop - settings . Freq . start ;
2020-08-31 04:03:41 +08:00
if ( center > old_span ) {
2021-07-10 04:26:44 +08:00
settings . Freq . start = center - old_span ;
2020-08-31 04:03:41 +08:00
} else {
2021-07-10 04:26:44 +08:00
settings . Freq . start = 0 ;
2020-08-31 04:03:41 +08:00
}
2021-07-10 04:26:44 +08:00
settings . Freq . stop = center + old_span ;
2020-08-31 04:03:41 +08:00
ConstrainAndUpdateFrequencies ( ) ;
}
2022-01-05 23:01:51 +08:00
void VNA : : SetLogSweep ( bool log )
{
if ( settings . Freq . logSweep ! = log ) {
settings . Freq . logSweep = log ;
emit logSweepChanged ( log ) ;
SettingsChanged ( ) ;
}
}
2020-08-31 04:03:41 +08:00
void VNA : : SetSourceLevel ( double level )
{
2022-08-05 18:20:41 +08:00
if ( level > VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxdBm ) {
level = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxdBm ;
} else if ( level < VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . mindBm ) {
level = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . mindBm ;
2020-08-31 04:03:41 +08:00
}
emit sourceLevelChanged ( level ) ;
2021-07-10 04:26:44 +08:00
settings . Freq . excitation_power = level ;
SettingsChanged ( ) ;
}
void VNA : : SetStartPower ( double level )
{
settings . Power . start = level ;
emit startPowerChanged ( level ) ;
2022-06-20 07:02:09 +08:00
ConstrainAndUpdateFrequencies ( ) ;
2021-07-10 04:26:44 +08:00
}
void VNA : : SetStopPower ( double level )
{
settings . Power . stop = level ;
emit stopPowerChanged ( level ) ;
2022-06-20 07:02:09 +08:00
ConstrainAndUpdateFrequencies ( ) ;
2021-07-10 04:26:44 +08:00
}
void VNA : : SetPowerSweepFrequency ( double freq )
{
settings . Power . frequency = freq ;
emit powerSweepFrequencyChanged ( freq ) ;
2020-08-31 04:03:41 +08:00
SettingsChanged ( ) ;
}
void VNA : : SetPoints ( unsigned int points )
{
2022-08-05 18:20:41 +08:00
unsigned int maxPoints = Preferences : : getInstance ( ) . Acquisition . allowSegmentedSweep ? UINT16_MAX : VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxPoints ;
2022-03-07 06:01:11 +08:00
if ( points > maxPoints ) {
points = maxPoints ;
2020-11-07 20:22:10 +08:00
} else if ( points < 2 ) {
2020-11-03 01:12:06 +08:00
points = 2 ;
2020-08-31 04:03:41 +08:00
}
2022-08-05 18:20:41 +08:00
if ( points > VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxPoints ) {
2022-03-07 06:01:11 +08:00
// needs segmented sweep
2022-08-05 18:20:41 +08:00
settings . segments = ceil ( ( double ) points / VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxPoints ) ;
2022-03-07 06:01:11 +08:00
settings . activeSegment = 0 ;
} else {
// can fit all points into one segment
settings . segments = 1 ;
settings . activeSegment = 0 ;
}
2020-08-31 04:03:41 +08:00
emit pointsChanged ( points ) ;
2021-07-10 04:26:44 +08:00
settings . npoints = points ;
2020-08-31 04:03:41 +08:00
SettingsChanged ( ) ;
}
void VNA : : SetIFBandwidth ( double bandwidth )
{
2022-08-05 18:20:41 +08:00
if ( bandwidth > VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxIFBW ) {
bandwidth = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxIFBW ;
} else if ( bandwidth < VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . minIFBW ) {
bandwidth = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . minIFBW ;
2020-09-27 05:34:31 +08:00
}
2021-07-10 04:26:44 +08:00
settings . bandwidth = bandwidth ;
emit IFBandwidthChanged ( settings . bandwidth ) ;
2020-08-31 04:03:41 +08:00
SettingsChanged ( ) ;
}
void VNA : : SetAveraging ( unsigned int averages )
{
this - > averages = averages ;
average . setAverages ( averages ) ;
emit averagingChanged ( averages ) ;
SettingsChanged ( ) ;
}
2022-08-05 18:20:41 +08:00
void VNA : : ExcitationRequired ( )
2020-09-16 05:22:08 +08:00
{
2022-08-09 00:08:40 +08:00
if ( ! Preferences : : getInstance ( ) . Acquisition . alwaysExciteAllPorts ) {
2022-08-05 18:20:41 +08:00
for ( int i = 1 ; i < VirtualDevice : : getInfo ( window - > getDevice ( ) ) . ports ; i + + ) {
auto required = traceModel . PortExcitationRequired ( i ) ;
auto set = find ( settings . excitedPorts . begin ( ) , settings . excitedPorts . end ( ) , i ) ! = settings . excitedPorts . end ( ) ;
if ( required ! = set ) {
// Required port excitation changed
SettingsChanged ( ) ;
break ;
}
}
2020-09-16 05:22:08 +08:00
}
}
2022-08-30 02:07:07 +08:00
void VNA : : DisableCalibration ( )
2020-08-31 04:03:41 +08:00
{
2022-08-30 02:07:07 +08:00
cal . deactivate ( ) ;
2020-08-31 04:03:41 +08:00
}
2022-08-30 02:07:07 +08:00
void VNA : : ApplyCalibration ( Calibration : : CalType type )
2020-08-31 04:03:41 +08:00
{
2022-08-30 02:07:07 +08:00
if ( cal . canCompute ( type ) ) {
2020-08-31 04:03:41 +08:00
try {
2022-08-30 02:07:07 +08:00
cal . compute ( type ) ;
2022-03-17 19:53:13 +08:00
} catch ( runtime_error & e ) {
2021-10-13 03:58:44 +08:00
InformationBox : : ShowError ( " Calibration failure " , e . what ( ) ) ;
2022-08-30 02:07:07 +08:00
DisableCalibration ( ) ;
2020-08-31 04:03:41 +08:00
}
} else {
2021-07-10 04:26:44 +08:00
if ( settings . sweepType = = SweepType : : Frequency ) {
// Not all required traces available
InformationBox : : ShowMessageBlocking ( " Missing calibration measurements " , " Not all calibration measurements for this type of calibration have been taken. The calibration can be enabled after the missing measurements have been acquired. " ) ;
2022-08-30 02:07:07 +08:00
DisableCalibration ( ) ;
cal . edit ( ) ;
2021-07-10 04:26:44 +08:00
} else {
// Not all required traces available
InformationBox : : ShowMessageBlocking ( " Missing calibration measurements " , " Not all calibration measurements for this type of calibration have been taken. Please switch to frequency sweep to take these measurements. " ) ;
2022-08-30 02:07:07 +08:00
DisableCalibration ( ) ;
2021-07-10 04:26:44 +08:00
}
2020-08-31 04:03:41 +08:00
}
}
2022-08-29 04:06:16 +08:00
void VNA : : StartCalibrationMeasurements ( std : : set < CalibrationMeasurement : : Base * > m )
2020-08-31 04:03:41 +08:00
{
2022-03-17 19:53:13 +08:00
if ( ! window - > getDevice ( ) ) {
2020-10-30 02:27:04 +08:00
return ;
}
// Stop sweep
StopSweep ( ) ;
2021-09-03 19:13:33 +08:00
calMeasurements = m ;
2020-08-31 04:03:41 +08:00
// Delete any already captured data of this measurement
2022-08-30 02:07:07 +08:00
cal . clearMeasurements ( m ) ;
2020-08-31 04:03:41 +08:00
calWaitFirst = true ;
2021-09-03 19:13:33 +08:00
// show messagebox
QString text = " Measuring " ;
if ( m . size ( ) = = 1 ) {
text . append ( " \" " ) ;
2022-08-29 04:06:16 +08:00
text . append ( CalibrationMeasurement : : Base : : TypeToString ( ( * m . begin ( ) ) - > getType ( ) ) ) ;
2021-09-03 19:13:33 +08:00
text . append ( " \" parameters. " ) ;
} else {
text . append ( " multiple calibration standards. " ) ;
}
2020-08-31 04:03:41 +08:00
calDialog . setLabelText ( text ) ;
calDialog . setCancelButtonText ( " Abort " ) ;
calDialog . setWindowTitle ( " Taking calibration measurement... " ) ;
calDialog . setValue ( 0 ) ;
calDialog . setWindowModality ( Qt : : ApplicationModal ) ;
// always show the dialog
calDialog . setMinimumDuration ( 0 ) ;
connect ( & calDialog , & QProgressDialog : : canceled , [ = ] ( ) {
// the user aborted the calibration measurement
calMeasuring = false ;
2022-08-30 02:07:07 +08:00
cal . clearMeasurements ( calMeasurements ) ;
2020-08-31 04:03:41 +08:00
} ) ;
2020-10-30 02:27:04 +08:00
// Trigger sweep to start from beginning
2022-08-05 18:20:41 +08:00
SettingsChanged ( true , [ = ] ( bool ) {
2020-10-30 02:27:04 +08:00
// enable calibration measurement only in transmission callback (prevents accidental sampling of data which was still being processed)
calMeasuring = true ;
} ) ;
2020-09-12 18:17:35 +08:00
}
2021-04-11 06:10:22 +08:00
void VNA : : SetupSCPI ( )
{
2021-07-12 00:41:05 +08:00
SCPINode : : add ( new SCPICommand ( " SWEEP " , [ = ] ( QStringList params ) - > QString {
if ( params . size ( ) > = 1 ) {
if ( params [ 0 ] = = " FREQUENCY " ) {
SetSweepType ( SweepType : : Frequency ) ;
return " " ;
} else if ( params [ 0 ] = = " POWER " ) {
SetSweepType ( SweepType : : Power ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-07-12 00:41:05 +08:00
}
}
// either no parameter or invalid
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2021-07-12 00:41:05 +08:00
} , [ = ] ( QStringList ) - > QString {
return settings . sweepType = = SweepType : : Frequency ? " FREQUENCY " : " POWER " ;
} ) ) ;
2021-04-11 06:10:22 +08:00
auto scpi_freq = new SCPINode ( " FREQuency " ) ;
SCPINode : : add ( scpi_freq ) ;
scpi_freq - > add ( new SCPICommand ( " SPAN " , [ = ] ( QStringList params ) - > QString {
2021-12-13 23:05:45 +08:00
unsigned long long newval ;
if ( ! SCPI : : paramToULongLong ( params , 0 , newval ) ) {
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2021-04-11 06:10:22 +08:00
} else {
SetSpan ( newval ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-04-11 06:10:22 +08:00
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2022-06-13 03:15:37 +08:00
return QString : : number ( settings . Freq . stop - settings . Freq . start , ' f ' , 0 ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
scpi_freq - > add ( new SCPICommand ( " START " , [ = ] ( QStringList params ) - > QString {
2021-12-13 23:05:45 +08:00
unsigned long long newval ;
if ( ! SCPI : : paramToULongLong ( params , 0 , newval ) ) {
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2021-04-11 06:10:22 +08:00
} else {
SetStartFreq ( newval ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-04-11 06:10:22 +08:00
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2022-06-13 03:15:37 +08:00
return QString : : number ( settings . Freq . start , ' f ' , 0 ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
2021-04-11 18:33:37 +08:00
scpi_freq - > add ( new SCPICommand ( " CENTer " , [ = ] ( QStringList params ) - > QString {
2021-12-13 23:05:45 +08:00
unsigned long long newval ;
if ( ! SCPI : : paramToULongLong ( params , 0 , newval ) ) {
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2021-04-11 06:10:22 +08:00
} else {
SetCenterFreq ( newval ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-04-11 06:10:22 +08:00
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2022-06-13 03:15:37 +08:00
return QString : : number ( ( settings . Freq . start + settings . Freq . stop ) / 2 , ' f ' , 0 ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
scpi_freq - > add ( new SCPICommand ( " STOP " , [ = ] ( QStringList params ) - > QString {
2021-12-13 23:05:45 +08:00
unsigned long long newval ;
if ( ! SCPI : : paramToULongLong ( params , 0 , newval ) ) {
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2021-04-11 06:10:22 +08:00
} else {
SetStopFreq ( newval ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-04-11 06:10:22 +08:00
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2022-06-13 03:15:37 +08:00
return QString : : number ( settings . Freq . stop , ' f ' , 0 ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
scpi_freq - > add ( new SCPICommand ( " FULL " , [ = ] ( QStringList params ) - > QString {
2021-04-13 01:48:19 +08:00
Q_UNUSED ( params )
2021-04-11 06:10:22 +08:00
SetFullSpan ( ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-04-11 06:10:22 +08:00
} , nullptr ) ) ;
2022-06-20 07:02:09 +08:00
scpi_freq - > add ( new SCPICommand ( " ZERO " , [ = ] ( QStringList params ) - > QString {
Q_UNUSED ( params )
SetZeroSpan ( ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2022-06-20 07:02:09 +08:00
} , nullptr ) ) ;
2021-07-12 00:41:05 +08:00
auto scpi_power = new SCPINode ( " POWer " ) ;
SCPINode : : add ( scpi_power ) ;
scpi_power - > add ( new SCPICommand ( " START " , [ = ] ( QStringList params ) - > QString {
double newval ;
if ( ! SCPI : : paramToDouble ( params , 0 , newval ) ) {
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2021-07-12 00:41:05 +08:00
} else {
SetStartPower ( newval ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-07-12 00:41:05 +08:00
}
} , [ = ] ( QStringList ) - > QString {
return QString : : number ( settings . Power . start ) ;
} ) ) ;
scpi_power - > add ( new SCPICommand ( " STOP " , [ = ] ( QStringList params ) - > QString {
double newval ;
if ( ! SCPI : : paramToDouble ( params , 0 , newval ) ) {
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2021-07-12 00:41:05 +08:00
} else {
SetStopPower ( newval ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-07-12 00:41:05 +08:00
}
} , [ = ] ( QStringList ) - > QString {
return QString : : number ( settings . Power . stop ) ;
} ) ) ;
2021-04-11 06:10:22 +08:00
auto scpi_acq = new SCPINode ( " ACQuisition " ) ;
SCPINode : : add ( scpi_acq ) ;
scpi_acq - > add ( new SCPICommand ( " IFBW " , [ = ] ( QStringList params ) - > QString {
2021-12-13 23:05:45 +08:00
unsigned long long newval ;
if ( ! SCPI : : paramToULongLong ( params , 0 , newval ) ) {
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2021-04-11 06:10:22 +08:00
} else {
SetIFBandwidth ( newval ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-04-11 06:10:22 +08:00
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2021-07-10 04:26:44 +08:00
return QString : : number ( settings . bandwidth ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
scpi_acq - > add ( new SCPICommand ( " POINTS " , [ = ] ( QStringList params ) - > QString {
2021-12-13 23:05:45 +08:00
unsigned long long newval ;
if ( ! SCPI : : paramToULongLong ( params , 0 , newval ) ) {
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2021-04-11 06:10:22 +08:00
} else {
SetPoints ( newval ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-04-11 06:10:22 +08:00
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2021-07-10 04:26:44 +08:00
return QString : : number ( settings . npoints ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
scpi_acq - > add ( new SCPICommand ( " AVG " , [ = ] ( QStringList params ) - > QString {
2021-12-13 23:05:45 +08:00
unsigned long long newval ;
if ( ! SCPI : : paramToULongLong ( params , 0 , newval ) ) {
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2021-04-11 06:10:22 +08:00
} else {
SetAveraging ( newval ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-04-11 06:10:22 +08:00
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2021-04-11 06:10:22 +08:00
return QString : : number ( averages ) ;
} ) ) ;
2021-06-12 00:53:31 +08:00
scpi_acq - > add ( new SCPICommand ( " AVGLEVel " , nullptr , [ = ] ( QStringList ) - > QString {
return QString : : number ( average . getLevel ( ) ) ;
} ) ) ;
scpi_acq - > add ( new SCPICommand ( " FINished " , nullptr , [ = ] ( QStringList ) - > QString {
2022-07-02 07:51:04 +08:00
return average . getLevel ( ) = = averages ? SCPI : : getResultName ( SCPI : : Result : : True ) : SCPI : : getResultName ( SCPI : : Result : : False ) ;
2021-06-12 00:53:31 +08:00
} ) ) ;
2022-04-22 19:46:46 +08:00
scpi_acq - > add ( new SCPICommand ( " LIMit " , nullptr , [ = ] ( QStringList ) - > QString {
return central - > allLimitsPassing ( ) ? " PASS " : " FAIL " ;
} ) ) ;
2022-05-18 02:07:40 +08:00
scpi_acq - > add ( new SCPICommand ( " SINGLE " , [ = ] ( QStringList params ) - > QString {
bool single ;
if ( ! SCPI : : paramToBool ( params , 0 , single ) ) {
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2022-05-18 02:07:40 +08:00
} else {
SetSingleSweep ( single ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2022-05-18 02:07:40 +08:00
}
} , [ = ] ( QStringList ) - > QString {
2022-07-02 07:51:04 +08:00
return singleSweep ? SCPI : : getResultName ( SCPI : : Result : : True ) : SCPI : : getResultName ( SCPI : : Result : : False ) ;
2022-05-18 02:07:40 +08:00
} ) ) ;
2021-04-11 06:10:22 +08:00
auto scpi_stim = new SCPINode ( " STIMulus " ) ;
SCPINode : : add ( scpi_stim ) ;
scpi_stim - > add ( new SCPICommand ( " LVL " , [ = ] ( QStringList params ) - > QString {
2021-04-14 03:33:51 +08:00
double newval ;
if ( ! SCPI : : paramToDouble ( params , 0 , newval ) ) {
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2021-04-11 06:10:22 +08:00
} else {
SetSourceLevel ( newval ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-04-11 06:10:22 +08:00
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2021-07-10 04:26:44 +08:00
return QString : : number ( settings . Freq . excitation_power ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
2021-07-12 00:41:05 +08:00
scpi_stim - > add ( new SCPICommand ( " FREQuency " , [ = ] ( QStringList params ) - > QString {
2021-12-13 23:05:45 +08:00
unsigned long long newval ;
if ( ! SCPI : : paramToULongLong ( params , 0 , newval ) ) {
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Error ) ;
2021-07-12 00:41:05 +08:00
} else {
SetPowerSweepFrequency ( newval ) ;
2022-07-02 07:51:04 +08:00
return SCPI : : getResultName ( SCPI : : Result : : Empty ) ;
2021-07-12 00:41:05 +08:00
}
} , [ = ] ( QStringList ) - > QString {
2022-06-13 03:15:37 +08:00
return QString : : number ( settings . Power . frequency , ' f ' , 0 ) ;
2021-07-12 00:41:05 +08:00
} ) ) ;
2021-04-13 01:48:19 +08:00
SCPINode : : add ( traceWidget ) ;
2022-10-01 08:05:30 +08:00
SCPINode : : add ( & cal ) ;
cal . add ( new SCPICommand ( " BUSy " , nullptr , [ = ] ( QStringList ) - > QString {
2022-07-02 07:51:04 +08:00
return CalibrationMeasurementActive ( ) ? SCPI : : getResultName ( SCPI : : Result : : True ) : SCPI : : getResultName ( SCPI : : Result : : False ) ;
2021-04-16 01:24:11 +08:00
} ) ) ;
2021-04-11 06:10:22 +08:00
}
2020-08-31 04:03:41 +08:00
void VNA : : ConstrainAndUpdateFrequencies ( )
{
2020-12-18 22:03:01 +08:00
auto pref = Preferences : : getInstance ( ) ;
double maxFreq ;
if ( pref . Acquisition . harmonicMixing ) {
2022-08-05 18:20:41 +08:00
maxFreq = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxFreqHarmonic ;
2020-12-18 22:03:01 +08:00
} else {
2022-08-05 18:20:41 +08:00
maxFreq = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . maxFreq ;
2020-12-18 22:03:01 +08:00
}
2021-07-10 04:26:44 +08:00
if ( settings . Freq . stop > maxFreq ) {
settings . Freq . stop = maxFreq ;
2020-08-31 04:03:41 +08:00
}
2021-07-10 04:26:44 +08:00
if ( settings . Freq . start > settings . Freq . stop ) {
settings . Freq . start = settings . Freq . stop ;
2020-08-31 04:03:41 +08:00
}
2022-08-05 18:20:41 +08:00
if ( settings . Freq . start < VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . minFreq ) {
settings . Freq . start = VirtualDevice : : getInfo ( window - > getDevice ( ) ) . Limits . minFreq ;
2020-09-27 05:34:31 +08:00
}
2022-06-20 07:02:09 +08:00
settings . zerospan = ( settings . sweepType = = SweepType : : Frequency & & settings . Freq . start = = settings . Freq . stop )
| | ( settings . sweepType = = SweepType : : Power & & settings . Power . start = = settings . Power . stop ) ;
2021-07-10 04:26:44 +08:00
emit startFreqChanged ( settings . Freq . start ) ;
emit stopFreqChanged ( settings . Freq . stop ) ;
emit spanChanged ( settings . Freq . stop - settings . Freq . start ) ;
emit centerFreqChanged ( ( settings . Freq . stop + settings . Freq . start ) / 2 ) ;
2020-08-31 04:03:41 +08:00
SettingsChanged ( ) ;
}
2020-09-12 05:07:15 +08:00
void VNA : : LoadSweepSettings ( )
{
2020-10-23 03:12:33 +08:00
auto pref = Preferences : : getInstance ( ) ;
2020-09-12 05:07:15 +08:00
QSettings s ;
2021-07-10 04:26:44 +08:00
// frequency sweep settings
settings . Freq . start = s . value ( " SweepFreqStart " , pref . Startup . DefaultSweep . f_start ) . toULongLong ( ) ;
settings . Freq . stop = s . value ( " SweepFreqStop " , pref . Startup . DefaultSweep . f_stop ) . toULongLong ( ) ;
SetSourceLevel ( s . value ( " SweepFreqLevel " , pref . Startup . DefaultSweep . f_excitation ) . toDouble ( ) ) ;
2022-01-08 07:49:00 +08:00
SetLogSweep ( s . value ( " SweepFreqLog " , pref . Startup . DefaultSweep . logSweep ) . toBool ( ) ) ;
2021-07-10 04:26:44 +08:00
// power sweep settings
SetStartPower ( s . value ( " SweepPowerStart " , pref . Startup . DefaultSweep . dbm_start ) . toDouble ( ) ) ;
SetStopPower ( s . value ( " SweepPowerStop " , pref . Startup . DefaultSweep . dbm_stop ) . toDouble ( ) ) ;
2021-07-10 20:04:05 +08:00
SetPowerSweepFrequency ( s . value ( " SweepPowerFreq " , pref . Startup . DefaultSweep . dbm_freq ) . toULongLong ( ) ) ;
2020-09-12 05:07:15 +08:00
SetPoints ( s . value ( " SweepPoints " , pref . Startup . DefaultSweep . points ) . toInt ( ) ) ;
2020-11-01 06:03:34 +08:00
SetIFBandwidth ( s . value ( " SweepBandwidth " , pref . Startup . DefaultSweep . bandwidth ) . toUInt ( ) ) ;
2020-10-23 17:39:07 +08:00
SetAveraging ( s . value ( " SweepAveraging " , pref . Startup . DefaultSweep . averaging ) . toInt ( ) ) ;
2020-11-01 06:03:34 +08:00
ConstrainAndUpdateFrequencies ( ) ;
2021-07-10 20:04:05 +08:00
auto typeString = s . value ( " SweepType " , pref . Startup . DefaultSweep . type ) . toString ( ) ;
if ( typeString = = " Power " ) {
SetSweepType ( SweepType : : Power ) ;
} else {
SetSweepType ( SweepType : : Frequency ) ;
}
2020-09-12 05:07:15 +08:00
}
void VNA : : StoreSweepSettings ( )
{
QSettings s ;
2021-07-10 04:26:44 +08:00
s . setValue ( " SweepType " , settings . sweepType = = SweepType : : Frequency ? " Frequency " : " Power " ) ;
s . setValue ( " SweepFreqStart " , static_cast < unsigned long long > ( settings . Freq . start ) ) ;
s . setValue ( " SweepFreqStop " , static_cast < unsigned long long > ( settings . Freq . stop ) ) ;
s . setValue ( " SweepFreqLevel " , settings . Freq . excitation_power ) ;
2022-01-08 07:49:00 +08:00
s . setValue ( " SweepFreqLog " , settings . Freq . logSweep ) ;
2021-07-10 04:26:44 +08:00
s . setValue ( " SweepPowerStart " , settings . Power . start ) ;
s . setValue ( " SweepPowerStop " , settings . Power . stop ) ;
s . setValue ( " SweepPowerFreq " , static_cast < unsigned long long > ( settings . Power . frequency ) ) ;
s . setValue ( " SweepBandwidth " , settings . bandwidth ) ;
s . setValue ( " SweepPoints " , settings . npoints ) ;
2020-10-23 17:39:07 +08:00
s . setValue ( " SweepAveraging " , averages ) ;
2020-09-12 05:07:15 +08:00
}
2020-10-30 02:27:04 +08:00
void VNA : : StopSweep ( )
{
if ( window - > getDevice ( ) ) {
2022-08-05 18:20:41 +08:00
window - > getDevice ( ) - > setIdle ( ) ;
2020-10-30 02:27:04 +08:00
}
}
2020-12-08 00:58:13 +08:00
void VNA : : UpdateCalWidget ( )
{
calLabel - > setStyleSheet ( getCalStyle ( ) ) ;
calLabel - > setToolTip ( getCalToolTip ( ) ) ;
}
2021-03-12 04:52:58 +08:00
2022-08-09 00:08:40 +08:00
void VNA : : createDefaultTracesAndGraphs ( int ports )
{
auto getDefaultColor = [ ] ( int ports , int i , int j ) - > QColor {
// Default colors for up to four ports, ensures that e.g. S21 always has the same color
const array < vector < QColor > , 4 > defaultColors = { {
{ Qt : : yellow } ,
{ Qt : : yellow , Qt : : blue , Qt : : green , Qt : : red } ,
{ Qt : : yellow , Qt : : blue , Qt : : cyan , Qt : : green , Qt : : red , Qt : : darkGreen , Qt : : darkBlue , Qt : : darkYellow , Qt : : magenta } ,
{ Qt : : yellow , Qt : : blue , Qt : : cyan , Qt : : darkCyan , Qt : : green , Qt : : red , Qt : : darkGreen , Qt : : gray , Qt : : darkBlue , Qt : : darkYellow , Qt : : magenta , Qt : : darkMagenta , Qt : : cyan , Qt : : darkGray , Qt : : lightGray , Qt : : darkRed } ,
} } ;
if ( ports > = 1 & & ports < = 4 ) {
return defaultColors [ ports - 1 ] [ i * ports + j ] ;
} else {
// not enough predefined colors available for all ports, just cycle through list
const array < QColor , 16 > list = { {
Qt : : yellow , Qt : : blue , Qt : : green , Qt : : red , Qt : : cyan , Qt : : magenta , Qt : : yellow , Qt : : darkRed , Qt : : darkGreen , Qt : : darkBlue , Qt : : gray , Qt : : darkCyan , Qt : : darkMagenta , Qt : : darkYellow , Qt : : darkGray , Qt : : lightGray
} } ;
auto index = ( i * ports + j ) % list . size ( ) ;
return list [ index ] ;
}
} ;
vector < vector < TracePlot * > > plots ;
for ( int i = 0 ; i < ports ; i + + ) {
plots . push_back ( vector < TracePlot * > ( ) ) ;
for ( int j = 0 ; j < ports ; j + + ) {
QString param = " S " + QString : : number ( i + 1 ) + QString : : number ( j + 1 ) ;
auto trace = new Trace ( param , getDefaultColor ( ports , i , j ) , param ) ;
traceModel . addTrace ( trace ) ;
TracePlot * plot ;
if ( i = = j ) {
plot = new TraceSmithChart ( traceModel ) ;
} else {
plot = new TraceXYPlot ( traceModel ) ;
}
plot - > updateSpan ( settings . Freq . start , settings . Freq . stop ) ;
plot - > enableTrace ( trace , true ) ;
plots [ i ] . push_back ( plot ) ;
}
}
// Add created graphs to tiles
central - > clear ( ) ;
TileWidget * tile = central ;
for ( int i = 0 ; i < ports ; i + + ) {
TileWidget * row ;
if ( i ! = ports - 1 ) {
// this is not the last row, split tile
tile - > splitVertically ( ) ;
row = tile - > Child1 ( ) ;
tile = tile - > Child2 ( ) ;
} else {
row = tile ;
}
for ( int j = 0 ; j < ports ; j + + ) {
TileWidget * graphTile ;
if ( j ! = ports - 1 ) {
row - > splitHorizontally ( ) ;
graphTile = row - > Child1 ( ) ;
row = row - > Child2 ( ) ;
} else {
graphTile = row ;
}
graphTile - > setPlot ( plots [ i ] [ j ] ) ;
}
}
if ( ports > = 3 ) {
// default split at the middle does not result in all plots being the same size, adjust
tile = central ;
for ( int i = 0 ; i < ports ; i + + ) {
TileWidget * rowTile ;
if ( i < ports - 1 ) {
tile - > setSplitPercentage ( 100 / ( ports - i ) ) ;
rowTile = tile - > Child1 ( ) ;
} else {
rowTile = tile ;
}
for ( int j = 0 ; j < ports - 1 ; j + + ) {
rowTile - > setSplitPercentage ( 100 / ( ports - j ) ) ;
rowTile = rowTile - > Child2 ( ) ;
}
tile = tile - > Child2 ( ) ;
}
}
}
2021-03-12 04:52:58 +08:00
void VNA : : EnableDeembedding ( bool enable )
{
deembedding_active = enable ;
enableDeembeddingAction - > blockSignals ( true ) ;
enableDeembeddingAction - > setChecked ( enable ) ;
enableDeembeddingAction - > blockSignals ( false ) ;
}
2021-06-29 10:47:02 +08:00
2021-12-02 05:11:50 +08:00
void VNA : : setAveragingMode ( Averaging : : Mode mode )
{
average . setMode ( mode ) ;
}
2022-08-09 00:08:40 +08:00
void VNA : : preset ( )
{
for ( auto t : traceModel . getTraces ( ) ) {
if ( Trace : : isVNAParameter ( t - > name ( ) ) ) {
traceModel . removeTrace ( t ) ;
}
}
// Create default traces
createDefaultTracesAndGraphs ( VirtualDevice : : getInfo ( window - > getDevice ( ) ) . ports ) ;
}
2021-09-04 01:01:22 +08:00
QString VNA : : SweepTypeToString ( VNA : : SweepType sw )
{
switch ( sw ) {
case SweepType : : Frequency : return " Frequency " ;
case SweepType : : Power : return " Power " ;
default : return " Unknown " ;
}
}
VNA : : SweepType VNA : : SweepTypeFromString ( QString s )
{
for ( int i = 0 ; i < ( int ) SweepType : : Last ; i + + ) {
if ( SweepTypeToString ( ( SweepType ) i ) = = s ) {
return ( SweepType ) i ;
}
}
// not found
return SweepType : : Last ;
}
2022-01-05 23:01:51 +08:00
2022-01-22 05:33:58 +08:00
void VNA : : UpdateStatusbar ( )
{
2022-08-30 02:07:07 +08:00
if ( cal . getCaltype ( ) . type ! = Calibration : : Type : : None ) {
2022-01-22 05:33:58 +08:00
QFileInfo fi ( cal . getCurrentCalibrationFile ( ) ) ;
auto filename = fi . fileName ( ) ;
if ( filename . isEmpty ( ) ) {
filename = " Unsaved " ;
}
setStatusbarMessage ( " Calibration: " + filename ) ;
} else {
setStatusbarMessage ( " Calibration: - " ) ;
}
}
2022-03-01 19:31:38 +08:00
2022-05-18 02:07:40 +08:00
void VNA : : SetSingleSweep ( bool single )
{
if ( singleSweep ! = single ) {
singleSweep = single ;
emit singleSweepChanged ( single ) ;
}
SettingsChanged ( ) ;
}
2022-03-01 19:31:38 +08:00
bool VNA : : LoadCalibration ( QString filename )
{
2022-08-30 02:07:07 +08:00
cal . fromFile ( filename ) ;
2022-03-01 19:31:38 +08:00
}