Qucs-S S-parameter Viewer & RF Synthesis Tools
Loading...
Searching...
No Matches
qucs-s-spar-viewer.h
1/*
2 * Copyright (C) 2025 Andrés Martínez Mera - andresmmera@protonmail.com
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#ifndef QUCSSPARVIEWER_H
19#define QUCSSPARVIEWER_H
20
21#include "../PlotWidgets/polarplotwidget.h"
22#include "../PlotWidgets/rectangularplotwidget.h"
23#include "../PlotWidgets/smithchartwidget.h"
24
25#include "../CustomWidgets/codeeditor.h"
26#include "../CustomWidgets/matrixcombopopup.h"
27
28#include "../Tools/AttenuatorDesign/AttenuatorDesignTool.h"
29#include "../Tools/Filtering/FilterDesignTool.h"
30#include "../Tools/MatchingNetwork/MatchingNetworkDesignTool.h"
31#include "../Tools/NetlistScratchPad/netlistscratchpad.h"
32#include "../Tools/PowerCombining/PowerCombiningTool.h"
33#include "../Tools/SimulationSetup/simulationsetup.h"
34
35#include "../SPAR/SParameterCalculator.h"
36
37#include "../Misc/general.h"
38
39#include <QCheckBox>
40#include <QColorDialog>
41#include <QDoubleSpinBox>
42#include <QGridLayout>
43#include <QLabel>
44#include <QMainWindow>
45#include <QScrollArea>
46#include <QTableWidget>
47#include <QtGlobal>
48#include <complex>
49
50class QComboBox;
51class QTableWidget;
52class QLineEdit;
53class QIntValidator;
54class QDoubleValidator;
55class QLabel;
56class QPushButton;
57
59 int x, y; // position of main window
60 QFont font;
61 QString LangDir;
62 QString Language;
63};
64
65extern struct tQucsSettings QucsSettings;
66
67// Struct to hold all the widgets related a marker
69 QLabel* nameLabel;
70 QDoubleSpinBox* freqSpinBox;
71 QComboBox* scaleComboBox;
72 QToolButton* deleteButton;
73};
74
75// Structures for trace management
76enum class DisplayMode {
77 Magnitude_dB,
78 Phase,
79 Smith,
80 Polar,
81 PortImpedance,
82 Stability,
83 VSWR,
84 GroupDelay
85};
86
87// Struct to hold all the widgets related a trace
89 QLabel* nameLabel;
90 QSpinBox* width;
91 QPushButton* colorButton;
92 QComboBox* LineStyleComboBox;
93 QToolButton* deleteButton;
94 QString display_mode;
95};
96
97// Struct to hold all the widgets related a limit
99 QLabel* LimitLabel;
100 QDoubleSpinBox* Start_Freq;
101 QDoubleSpinBox* Stop_Freq;
102 QDoubleSpinBox* Start_Value;
103 QDoubleSpinBox* Stop_Value;
104 QComboBox* Start_Freq_Scale;
105 QComboBox* Stop_Freq_Scale;
106 QComboBox* axis;
107 QToolButton* Button_Delete_Limit;
108 QFrame* Separator;
109 QPushButton* Couple_Value;
110};
111
112// Structure to hold trace information
113struct TraceInfo {
114 QString dataset;
115 QString parameter; // e.g., "S11", "S21"
116 DisplayMode displayMode;
117
118 // Helper to generate a unique identifier for the trace
119 QString uniqueId() const {
120 if ((displayMode == DisplayMode::Magnitude_dB) ||
121 (displayMode == DisplayMode::Phase)) {
122 return QString("%1.%2_%3")
123 .arg(dataset)
124 .arg(parameter)
125 .arg(static_cast<int>(displayMode));
126 } else {
127 return QString("%1.%2").arg(dataset).arg(parameter);
128 }
129 }
130
131 // Helper to get a human-readable name for the trace
132 QString displayName() const {
133 QString modeName = QString("");
134
135 if (displayMode == DisplayMode::Magnitude_dB) {
136 modeName = "dB";
137 } else {
138 if (displayMode == DisplayMode::Phase) {
139 modeName = "Phase";
140 } else {
141 return QString("%1.%2").arg(dataset).arg(parameter);
142 }
143 }
144 return QString("%1.%2_%3").arg(dataset).arg(parameter).arg(modeName);
145 }
146};
147
148class Qucs_S_SPAR_Viewer : public QMainWindow {
149 Q_OBJECT
150public:
153 void
154 addPathToWatcher(const QString& path); // It's needed to pass the directory to
155 // watch from the main program
156 void addFile(const QFileInfo&
157 fileInfo); // The main qucs program uses this function to
158 // open a Touchstone file from the Project View
159
160private slots:
161 void slotHelpIntro();
162 void slotHelpAbout();
163 void slotHelpAboutQt();
164 void slotQuit();
165 void slotSave();
166 void slotSaveAs();
167 void slotLoadSession();
168
169 void raiseWidgetsOnTabSelection(int index);
170
171 void addFile();
172 void addFiles(QStringList);
173 QMap<QString, QList<double>> readQucsatorDataset(const QString& filePath);
174 QMap<QString, QList<double>> readNGspiceData(const QString& filePath);
175 QString extractSParamIndices(const QString& sparam);
176 void applyDefaultVisualizations(const QStringList& fileNames);
177 void addOptionalTraces(QMap<QString, QList<double>>& file_data);
178 void removeFile();
179 void removeFile(QString ID);
180 void removeAllFiles();
181 void removeTracesByDataset(const QString& dataset_to_remove);
182 void removeTraceByProps(DisplayMode mode, const QString& traceID,
183 TraceProperties& props);
184 void CreateFileWidgets(QString filename, int position = 0);
185
186 // File watching functions
187 void setupFileWatcher();
188 void fileChanged(const QString& path);
189 void directoryChanged(const QString& path);
190
191 void addTrace();
192 void addTrace(const TraceInfo& traceInfo, QColor trace_color, int trace_width,
193 QString trace_style = "Solid");
194 void removeTrace();
195 // void removeTrace(const QString& );
196 // void removeTrace(QStringList);
197 void removeAndCollapseRow(QGridLayout* targetLayout, int row_to_remove);
198 int getNumberOfTraces();
199 // bool getTraceByPosition(int position, QString& outTraceName,
200 // TraceProperties& outProperties);
201 void cleanToolsDatasets(const QString& excludeDataset = QString());
202
203 void updateTracesCombo();
204 void updateDisplayType();
205
206 void changeTraceColor();
207 void changeTraceLineStyle();
208 void changeTraceWidth();
209 void changeMarkerLimits();
210 void changeMarkerLimits(QString);
211
212 void addMarker(double freq = -1, QString Freq_Marker_Scale = QString("MHz"));
213 void removeMarker();
214 void removeMarker(const QString&);
215 void removeAllMarkers();
216 int getNumberOfMarkers();
217 void updateMarkerTable();
218 void updateMarkerNames();
219 void updateMarkerData(QTableWidget& layout, DisplayMode mode,
220 QStringList header);
221 bool getMarkerByPosition(int position, QString& outMarkerName,
222 MarkerProperties& outProperties);
223
224 void addLimit(double f_limit1 = -1, QString f_limit1_unit = "",
225 double f_limit2 = -1, QString f_limit2_unit = "",
226 double y_limit1 = -1, double y_limit2 = -1,
227 bool coupled = true);
228 void removeLimit();
229 void removeLimit(QString);
230 void removeAllLimits();
231 void updateLimits();
232 void updateLimitNames();
233 int getNumberOfLimits();
234 bool getLimitByPosition(int, QString&, LimitProperties&);
235
236 void coupleSpinBoxes();
237
238 void updateGridLayout(QGridLayout*);
239 void updateAllPlots(const QString& datasetName);
240 void updateTracesInWidget(QWidget* widget, const QString& datasetName);
241
242 void calculate_Sparameter_trace(QString, QString);
243
244protected:
245 void dragEnterEvent(QDragEnterEvent* event) override;
246 void dropEvent(QDropEvent* event) override;
247
248private:
249 QDockWidget* dockFiles;
250 QTableWidget* spar_files_Widget;
251 QPushButton *Button_Add_File, *Delete_All_Files;
252
253 // File list
254 QList<QPushButton*> Button_DeleteFile;
255
256 // Filenames and remove buttons
257 QVBoxLayout* vLayout_Files;
258 QWidget* FileList_Widget;
259 QGridLayout* FilesGrid;
260 QList<QLabel*> List_FileNames;
261 QList<QToolButton*> List_RemoveButton;
262
263 // Trace list
264 QDockWidget* dockTracesList;
265 QWidget* TracesList_Widget;
266 QGridLayout* TracesGrid;
267
268 // This structure groups the widgets related to the traces so that they can be
269 // accessed by name
270 QMap<DisplayMode, QMap<QString, TraceProperties>> traceMap;
271
272 QTabWidget* traceTabs;
273 QWidget *magnitudePhaseTab, *smithTab, *polarTab, *portImpedanceTab,
274 *stabilityTab, *VSWRTab, *GroupDelayTab;
275 QGridLayout *magnitudePhaseLayout, *smithLayout, *polarLayout,
276 *portImpedanceLayout, *stabilityLayout, *VSWRLayout, *GroupDelayLayout;
277
278 // Axis settings widgets
279 QPushButton* Lock_axis_settings_Button;
280 bool lock_axis;
281 QStringList frequency_units;
282
283 // Trace management widgets
284 QComboBox *QCombobox_datasets, *QCombobox_display_mode;
285 MatrixComboBox* QCombobox_traces;
286 QPushButton* Button_add_trace;
287 QTableWidget* Traces_Widget;
288
289 // Scrollable trace areas
290 void setupScrollableLayout();
291 void setupScrollAreaForLayout(QGridLayout*& layout, QWidget* parentTab,
292 const QString& objectName);
293 QScrollArea *magnitudePhaseScrollArea, *smithScrollArea, *polarScrollArea,
294 *nuScrollArea, *GroupDelayScrollArea;
295
296 // Datasets
297 QMap<QString, QMap<QString, QList<double>>> datasets;
298
299 /*
300 KEY | DATA
301 Filename1.s2p | {"freq", "S11_dB", ..., "S22_ang"}
302 ... | ...
303 Filenamek.s3p | {"freq", "S11_dB", ..., "S33_ang"}
304 */
305
306 // File watching variables
307 QFileSystemWatcher* fileWatcher;
308 QMap<QString, QString> watchedFilePaths;
309
310 // Rectangular plot
311 RectangularPlotWidget* Magnitude_PhaseChart;
312 QDockWidget* dockChart;
313 double f_min, f_max; // Minimum (maximum) values of the display
314 QList<QColor> default_colors;
315 QList<QGraphicsItem*> textLabels;
316
317 // Smith Chart
318 SmithChartWidget* smithChart;
319 QDockWidget* dockSmithChart;
320 QList<SmithChartWidget::Trace> SmithChartTraces;
321
322 // Polar plot
323 PolarPlotWidget* polarChart;
324 QDockWidget* dockPolarChart;
325 QList<PolarPlotWidget::Trace> PolarChartTraces;
326
327 // Port impedance plot (Rectangular plot)
328 RectangularPlotWidget* impedanceChart;
329 QDockWidget* dockImpedanceChart;
330 QList<RectangularPlotWidget::Trace> impedanceChartTraces;
331
332 // Stability plot (Rectangular plot)
333 RectangularPlotWidget* stabilityChart;
334 QDockWidget* dockStabilityChart;
335 QList<RectangularPlotWidget::Trace> stabilityChartTraces;
336
337 // VSWR plot (Rectangular plot)
338 RectangularPlotWidget* VSWRChart;
339 QDockWidget* dockVSWRChart;
340 QList<RectangularPlotWidget::Trace> VSWRChartTraces;
341
342 // Group delay plot (Rectangular plot)
343 RectangularPlotWidget* GroupDelayChart;
344 QDockWidget* dockGroupDelayChart;
345 QList<RectangularPlotWidget::Trace> GroupDelayTraces;
346
347 // Markers
348 QDockWidget* dockMarkers;
349 QWidget* Marker_Widget;
350 QGridLayout* MarkersGrid;
351 QPushButton *Button_add_marker, *Button_Remove_All_Markers;
352 QTableWidget *tableMarkers_Magnitude_Phase, *tableMarkers_Smith,
353 *tableMarkers_Polar, *tableMarkers_PortImpedance, *tableMarkers_Stability,
354 *tableMarkers_VSWR, *tableMarkers_GroupDelay;
355 QMap<QString, MarkerProperties>
356 markerMap; // All marker widgets are here. This way they can be accessed
357 // by the name of the marker
358
359 double getMarkerFreq(QString);
360
361 // Limits
362 QDockWidget* dockLimits;
363 QWidget* Limits_Widget;
364 QGridLayout* LimitsGrid;
365 QPushButton *Button_add_Limit, *Button_Remove_All_Limits;
366 QDoubleSpinBox* Limits_Offset;
367 QMap<QString, LimitProperties>
368 limitsMap; // This structure groups the widgets related to the traces so
369 // that they can be accessed by name
370
371 // Tools
372 QDockWidget* dockTools;
373 GraphWidget* SchematicWidget; // Schematic viewer
374 QTabWidget*
375 toolsTabWidget; // Tools' tab widget. It contains all the RF design tools
376 SimulationSetup* SimulationSetupWidget;
378 Circuit; // Description of the circuit in the schematic.
379 // It needs to be a member variable since the simulation can be
380 // triggered by a change in the simulation settings.
381 // i.e. in this case there's no SchematicContent object to emit
382 NetlistScratchPad* Netlist_Tool;
383
384 // Export schematic
385 QLabel* LabelExportSchematic;
386 QPushButton* ButtonExportSchematic;
387 QComboBox* ComboExportSchematic, *ComboExportOutputMethod;
388
389 void
390 updateSchematicContent(); // This is called by the updateSimulation() function
391
392 void callTools(bool visible);
393 void onToolsTabChanged(int index);
394
395 // Tools
396 QTabWidget* toolsTabs;
397 QStringList
398 Tools_Datasets; // This is required for cleaning the datasets generated by
399 // the design tools when the tab is switched
400
401 // Filter Tool
402 QWidget* FilterToolTab;
403 FilterDesignTool* FilterTool;
404
405 // Matching network tool
406 QWidget* MatchingToolTab;
407 MatchingNetworkDesignTool* MatchingTool;
408
409 // Power Combining Tool
410 PowerCombiningTool* PowerCombTool;
411
412 // Attenuator Design Tool
413 AttenuatorDesignTool* AttenuatorTool;
414
415 // S-parameter simulation class
416 SParameterCalculator SPAR_engine;
417
418 // Substrate
419 MS_Substrate MS_Subs;
420
421 // Save
422 QString savepath;
423 bool save();
424 void loadSession(QString);
425
426 // Save rectangular plot settings
427 void saveRectangularPlotSettings(QXmlStreamWriter& xml,
428 RectangularPlotWidget* widget,
429 const QString& elementName);
430 void loadRectangularPlotSettings(QXmlStreamReader& xml,
431 RectangularPlotWidget* widget,
432 const QString& elementName);
433
434 void saveSmithPlotSettings(QXmlStreamWriter& xml, SmithChartWidget* widget,
435 const QString& elementName);
436 void loadSmithPlotSettings(QXmlStreamReader& xml, SmithChartWidget* widget,
437 const QString& elementName);
438
439 void savePolarPlotSettings(QXmlStreamWriter& xml, PolarPlotWidget* widget,
440 const QString& elementName);
441 void loadPolarPlotSettings(QXmlStreamReader& xml, PolarPlotWidget* widget,
442 const QString& elementName);
443
444 // Notes
445 QDockWidget* dockNotes;
446 CodeEditor* Notes_Widget;
447
448 // Recent files
449 std::vector<QString> recentFiles;
450 QMenu* recentFilesMenu;
451 void updateRecentFilesMenu();
452 void loadRecentFiles();
453 void addRecentFile(const QString&);
454 void clearRecentFiles();
455 void saveRecentFiles();
456
457 // Setup UI
458 void CreateMenuBar();
459 void CreateDisplayWidgets(); // Setup magnitude/phase and Smith charts
460
461 void CreateRightPanel(); // Setup managing docks
462 void setFileManagementDock(); // Setup file management dock
463 void setTraceManagementDock(); // Setup trace management dock
464 void setMarkerManagementDock(); // Setup marker management dock
465 void setLimitManagementDock(); // Setup limit management dock
466 void setToolsDock(); // Setup limit management dock
467
468 // Utilities
469 void getMinMaxValues(QString, QString, qreal&, qreal&, qreal&, qreal&);
470 void adjust_x_axis_to_file(QString);
471 void adjust_y_axis_to_trace(QString, QString);
472 void adjust_x_axis_div();
473
474 // File monitoring
475 void setupSimulationWatcher();
476 QStringList getWatchDirectories() const;
477 bool isSparamFile(const QString& path); // Used to accept only data files when
478 // scanning project directories
479 QStringList filePaths; // Full path of the files in the progrom. It's used for
480 // file monitoring.
481
482private slots:
483 void updateSimulation(
484 SchematicContent SI); // Updates the traces from the designer tools
485 void updateSimulation();
486 void updateSubstrate();
487 void exportSchematic(); // to Qucs-S or whatever
488};
489
490#endif
Definition AttenuatorDesignTool.h:56
[codeeditordefinition]
Definition codeeditor.h:67
Definition FilterDesignTool.h:57
[0]
Definition graphwidget.h:60
Definition MatchingNetworkDesignTool.h:40
ComboBox with custom matrix-style popup for parameter selection.
Definition matrixcombopopup.h:44
Definition netlistscratchpad.h:29
Definition polarplotwidget.h:33
Definition PowerCombiningTool.h:82
Definition qucs-s-spar-viewer.h:148
Definition rectangularplotwidget.h:34
Definition SParameterCalculator.h:118
Definition SchematicContent.h:33
Definition simulationsetup.h:40
Definition smithchartwidget.h:36
Definition qucs-s-spar-viewer.h:98
Definition structures.h:92
Definition qucs-s-spar-viewer.h:68
Definition qucs-s-spar-viewer.h:113
Definition qucs-s-spar-viewer.h:88
Definition qucs-s-spar-viewer.h:58