KiCad PCB EDA Suite
Loading...
Searching...
No Matches
simulator_frame_ui.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2016-2023 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Tomasz Wlostowski <[email protected]>
8 * @author Maciej Suminski <[email protected]>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 3
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24#pragma once
25
26
28#include <sim/sim_types.h>
29#include <sim/sim_plot_tab.h>
30#include <sim/sim_preferences.h>
31
32#include <wx/event.h>
33
34class SCH_EDIT_FRAME;
35class SCH_SYMBOL;
36
37class SPICE_SIMULATOR;
38class SPICE_SETTINGS;
41
42class TUNER_SLIDER;
44
45
63
64
66{
67public:
68 SIMULATOR_FRAME_UI( SIMULATOR_FRAME* aSimulatorFrame, SCH_EDIT_FRAME* aSchematicFrame );
70
76 SIM_TAB* NewSimTab( const wxString& aSimCommand );
77
78 std::vector<wxString> SimPlotVectors() const;
79
80 std::vector<wxString> Signals() const;
81
82 const std::map<int, wxString>& UserDefinedSignals() { return m_userDefinedSignals; }
83 void SetUserDefinedSignals( const std::map<int, wxString>& aSignals );
84
91 void CreateNewCursor();
92
98 void DeleteCursor();
99
106 void AddTrace( const wxString& aName, SIM_TRACE_TYPE aType );
107
112 SPICE_VALUE_FORMAT GetCursorFormat( int aCursorId, int aValueCol ) const
113 {
114 return m_cursorFormatsDyn[aCursorId][aValueCol];
115 }
116
117 void SetCursorFormat( int aCursorId, int aValueCol, const SPICE_VALUE_FORMAT& aFormat )
118 {
119 m_cursorFormatsDyn[ aCursorId ][ aValueCol ] = aFormat;
120
121 wxCommandEvent dummy;
123 }
124
128 void AddTuner( const SCH_SHEET_PATH& aSheetPath, SCH_SYMBOL* aSymbol );
129
133 void RemoveTuner( TUNER_SLIDER* aTuner );
134
143 void UpdateTunerValue( const SCH_SHEET_PATH& aSheetPath, const KIID& aSymbol,
144 const wxString& aRef, const wxString& aValue );
145
149 void AddMeasurement( const wxString& aCmd );
150
154 void DeleteMeasurement( int aRow );
155
159 SPICE_VALUE_FORMAT GetMeasureFormat( int aRow ) const;
160 void SetMeasureFormat( int aRow, const SPICE_VALUE_FORMAT& aFormat );
161
165 void UpdateMeasurement( int aRow );
166
167 void DoFourier( const wxString& aSignal, const wxString& aFundamental );
168
172 const SPICE_CIRCUIT_MODEL* GetExporter() const;
173
174 bool IsSimConsoleShown();
175 void ToggleSimConsole();
176 bool IsSimSidePanelShown();
177 void ToggleSimSidePanel();
178
179 bool DarkModePlots() const { return m_darkMode; }
180 void ToggleDarkModePlots();
181
183 void ToggleSmithChart();
184
185 void ShowChangedLanguage();
186
191 void InitWorkbook();
192
196 bool LoadWorkbook( const wxString& aPath );
197
201 bool SaveWorkbook( const wxString& aPath );
202
203 void LoadSettings( EESCHEMA_SETTINGS* aCfg );
204
205 void SaveSettings( EESCHEMA_SETTINGS* aCfg );
206
210 void ApplyPreferences( const SIM_PREFERENCES& aPrefs );
211
219
224 {
225 return dynamic_cast<SIM_TAB*>( m_plotNotebook->GetCurrentPage() );
226 }
227
228 SIM_TAB* GetSimTab( SIM_TYPE aType ) const
229 {
230 for( int ii = 0; ii < (int) m_plotNotebook->GetPageCount(); ++ii )
231 {
232 SIM_TAB* candidate = dynamic_cast<SIM_TAB*>( m_plotNotebook->GetPage( ii ) );
233
234 if( candidate && candidate->GetSimType() == aType )
235 return candidate;
236 }
237
238 return nullptr;
239 }
240
241 int GetSimTabIndex( SIM_TAB* aPlot ) const
242 {
243 return m_plotNotebook->GetPageIndex( aPlot );
244 }
245
252 bool IsPlotOwnedByOtherTab( const SIM_TAB* aExcept, const wxString& aPlotName ) const
253 {
254 if( aPlotName.IsEmpty() )
255 return false;
256
257 for( int ii = 0; ii < (int) m_plotNotebook->GetPageCount(); ++ii )
258 {
259 SIM_TAB* candidate = dynamic_cast<SIM_TAB*>( m_plotNotebook->GetPage( ii ) );
260
261 if( candidate && candidate != aExcept && candidate->GetSpicePlotName() == aPlotName )
262 return true;
263 }
264
265 return false;
266 }
267
269
270 void OnSimUpdate();
271 void OnSimRefresh( bool aFinal );
272 void FlushSimConsole();
273
274 void OnModify();
275
276private:
280 wxString vectorNameFromSignalName( SIM_PLOT_TAB* aPlotTab, const wxString& aSignalName, int* aTraceType );
281
292 void updateTrace( const wxString& aVectorName, int aTraceType, SIM_PLOT_TAB* aPlotTab,
293 std::vector<double>* aDataX = nullptr, bool aClearData = false, SIM_VIEW* aView = nullptr );
294
296 double getSmithPortImpedance( const wxString& aVectorName );
297
301 void TogglePanel( wxPanel* aPanel, wxSplitterWindow* aSplitterWindow, int& aSashPosition );
302
308 void CustomCursorsInit();
309
315 void rebuildSignalsList();
316
320 void rebuildSignalsGrid( wxString aFilter );
321
325 void updateSignalsGrid();
326
330 void updatePlotCursors();
331
335 void updateSmithCursorColumns( bool aSmithMode );
336
337 void fillSmithCursorRow( int aRow, CURSOR* aCursor, TRACE* aTrace );
338
340
342
344
352 template <typename T, typename U, typename R>
353 void signalsGridCursorUpdate( T t, U u, R r );
354
359
364
366
373 void autoSizeGridColumn( WX_GRID* aGrid, int aCol, int aMinWidth, int aExtraPadding = 0 );
374
376 wxArrayString getViewChoices( SIM_PLOT_TAB* aPlotTab ) const;
377
379 wxString getViewLabel( SIM_PLOT_TAB* aPlotTab, SIM_VIEW* aView ) const;
380
383 std::vector<SIM_VIEW*> getYScaleTargetViews( SIM_PLOT_TAB* aPlotTab, SIM_VIEW* aOwnView ) const;
384
386 wxArrayString getYScaleChoices( SIM_PLOT_TAB* aPlotTab, SIM_VIEW* aOwnView ) const;
387
389 wxString getYScaleLabel( SIM_PLOT_TAB* aPlotTab, TRACE* aTrace ) const;
390
394 void applyTuners();
395
399 SIM_TRACE_TYPE getXAxisType( SIM_TYPE aType ) const;
400
401 struct MULTI_RUN_STEP;
402
403 void clearMultiRunState( bool aClearTraces );
405 std::vector<MULTI_RUN_STEP> calculateMultiRunSteps( const std::vector<TUNER_SLIDER*>& aTuners ) const;
406 std::string multiRunTraceKey( const wxString& aVectorName, int aTraceType ) const;
407 void recordMultiRunData( const wxString& aVectorName, int aTraceType,
408 const std::vector<double>& aX, const std::vector<double>& aY );
409 bool hasMultiRunTrace( const wxString& aVectorName, int aTraceType ) const;
410
411 wxString getNoiseSource() const;
412
413 void parseTraceParams( SIM_PLOT_TAB* aPlotTab, TRACE* aTrace, const wxString& aSignalName,
414 const wxString& aParams );
415
416 std::shared_ptr<SPICE_SIMULATOR> simulator() const;
417 std::shared_ptr<SPICE_CIRCUIT_MODEL> circuitModel() const;
418
419 // Event handlers
420 void onPlotClose( wxAuiNotebookEvent& event ) override;
421 void onPlotClosed( wxAuiNotebookEvent& event ) override;
422 void onPlotChanging( wxAuiNotebookEvent& event ) override;
423 void onPlotChanged( wxAuiNotebookEvent& event ) override;
424 void onPlotDragged( wxAuiNotebookEvent& event ) override;
425
426 void OnFilterText( wxCommandEvent& aEvent ) override;
427 void OnFilterMouseMoved( wxMouseEvent& aEvent ) override;
428
429 void onSignalsGridCellChanged( wxGridEvent& aEvent ) override;
430 void onCursorsGridCellChanged( wxGridEvent& aEvent ) override;
431 void onMeasurementsGridCellChanged( wxGridEvent& aEvent ) override;
432
433 void OnUpdateUI( wxUpdateUIEvent& event ) override;
434
435 bool loadLegacyWorkbook( const wxString & aPath );
436 bool loadJsonWorkbook( const wxString & aPath );
437
438 void SaveCursorToWorkbook( nlohmann::json& aTraceJs, TRACE* aTrace, int aCursorId );
439
440 void onPlotCursorUpdate( wxCommandEvent& aEvent );
441
442public:
444
445private:
448
451
452 std::vector<wxString> m_signals;
453 std::map<int, wxString> m_userDefinedSignals;
454 std::list<TUNER_SLIDER*> m_tuners;
455 std::map<const TUNER_SLIDER*, double> m_tunerOverrides;
456
458 {
460 std::vector<double> xValues;
461 std::vector<std::vector<double>> yValues;
462
463 // smith traces carry Re(gamma) in x, different every run, stored per run here
464 std::vector<std::vector<double>> xRuns;
465 };
466
468 {
469 std::map<const TUNER_SLIDER*, double> overrides;
470 };
471
473 {
474 bool active = false;
475 std::vector<TUNER_SLIDER*> tuners;
476 std::vector<MULTI_RUN_STEP> steps;
477 size_t currentStep = 0;
478 size_t storedSteps = 0;
479 bool storePending = false;
480 std::map<std::string, MULTI_RUN_TRACE> traces;
481 };
482
484
487 std::vector<wxString> m_netnames;
488
490
491 // Holds cursor formating for m_cursorsGrid, includes m_cursorFormats[3][2], TODO: merge.
492 std::vector<std::vector<SPICE_VALUE_FORMAT>> m_cursorFormatsDyn;
493
495 std::vector<int> m_smithCursorWidths;
496
497 // Variables for temporary storage:
504 unsigned int m_plotNumber;
507
508 // Count all available cursors in m_signalsGrid
509 int m_customCursorsCnt; // Defaults to 2 + 1
510};
The SIMULATOR_FRAME holds the main user-interface for running simulations.
Definition kiid.h:46
Schematic editor (Eeschema) main window.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Schematic symbol object.
Definition sch_symbol.h:75
SIMULATOR_FRAME_UI_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
SIM_TAB * NewSimTab(const wxString &aSimCommand)
Create a new simulation tab for a given simulation type.
std::string multiRunTraceKey(const wxString &aVectorName, int aTraceType) const
std::vector< int > m_smithCursorWidths
void SetUserDefinedSignals(const std::map< int, wxString > &aSignals)
void updatePlotCursors()
Update the cursor values (in the grid) and graphics (in the plot window).
void OnSimRefresh(bool aFinal)
void onPlotClose(wxAuiNotebookEvent &event) override
void CustomCursorsInit()
Init handler for custom cursors.
void recordMultiRunData(const wxString &aVectorName, int aTraceType, const std::vector< double > &aX, const std::vector< double > &aY)
std::vector< MULTI_RUN_STEP > calculateMultiRunSteps(const std::vector< TUNER_SLIDER * > &aTuners) const
void autoSizeGridColumn(WX_GRID *aGrid, int aCol, int aMinWidth, int aExtraPadding=0)
Grow (but never shrink below aMinWidth) a grid column to fit its current contents.
void TogglePanel(wxPanel *aPanel, wxSplitterWindow *aSplitterWindow, int &aSashPosition)
A common toggler for the two main wxSplitterWindow s.
void onPlotChanged(wxAuiNotebookEvent &event) override
void rebuildSignalsGrid(wxString aFilter)
Rebuild the filtered list of signals in the signals grid.
SIM_TAB * GetSimTab(SIM_TYPE aType) const
std::vector< std::vector< SPICE_VALUE_FORMAT > > m_cursorFormatsDyn
void DoFourier(const wxString &aSignal, const wxString &aFundamental)
void rebuildMeasurementsGrid()
Rebuild the measurements grid for the current plot.
std::list< TUNER_SLIDER * > m_tuners
bool IsPlotOwnedByOtherTab(const SIM_TAB *aExcept, const wxString &aPlotName) const
Return true if a tab other than aExcept records aPlotName as its ngspice plot.
void rebuildSignalsList()
Rebuild the list of signals available from the netlist.
bool loadLegacyWorkbook(const wxString &aPath)
MULTI_RUN_STATE m_multiRunState
SPICE expressions need quoted versions of the netnames since KiCad allows '-' and '/' in netnames.
wxArrayString getYScaleChoices(SIM_PLOT_TAB *aPlotTab, SIM_VIEW *aOwnView) const
The Signals grid's "Y Scale" column label for a trace ("Default" if not explicitly linked).
void UpdateMeasurement(int aRow)
Update a measurement in the measurements grid.
wxString getNoiseSource() const
std::vector< wxString > SimPlotVectors() const
void SetSubWindowsSashSize()
Adjust the sash dimension of splitter windows after reading the config settings must be called after ...
void applyUserDefinedSignals()
Apply user-defined signals to the SPICE session.
SIM_PREFERENCES m_preferences
void DeleteMeasurement(int aRow)
Delete a row from the measurements grid.
SCH_EDIT_FRAME * m_schematicFrame
wxString vectorNameFromSignalName(SIM_PLOT_TAB *aPlotTab, const wxString &aSignalName, int *aTraceType)
Get the simulator output vector name for a given signal name and type.
void updateSignalsGrid()
Update the values in the signals grid.
void onCursorsGridCellChanged(wxGridEvent &aEvent) override
void onPlotDragged(wxAuiNotebookEvent &event) override
std::vector< wxString > Signals() const
bool SaveWorkbook(const wxString &aPath)
Save plot, signal, cursor, measurement, etc.
bool hasMultiRunTrace(const wxString &aVectorName, int aTraceType) const
std::vector< wxString > m_signals
SIM_TAB * GetCurrentSimTab() const
Return the currently opened plot panel (or NULL if there is none).
wxString getViewLabel(SIM_PLOT_TAB *aPlotTab, SIM_VIEW *aView) const
The views a trace's Y-axis scale could be linked to: every view except its own (since linking to its ...
void updateSmithCursorColumns(bool aSmithMode)
Add or remove the Smith-only cursor columns, carrying their shown/hidden state across.
void SaveCursorToWorkbook(nlohmann::json &aTraceJs, TRACE *aTrace, int aCursorId)
bool LoadWorkbook(const wxString &aPath)
Load plot, signal, cursor, measurement, etc.
wxString getYScaleLabel(SIM_PLOT_TAB *aPlotTab, TRACE *aTrace) const
SPICE_VALUE_FORMAT GetMeasureFormat(int aRow) const
Get/Set the format of a value in the measurements grid.
std::map< int, wxString > m_userDefinedSignals
void updateTrace(const wxString &aVectorName, int aTraceType, SIM_PLOT_TAB *aPlotTab, std::vector< double > *aDataX=nullptr, bool aClearData=false, SIM_VIEW *aView=nullptr)
Update a trace in a particular SIM_PLOT_TAB.
void UpdateTunerValue(const SCH_SHEET_PATH &aSheetPath, const KIID &aSymbol, const wxString &aRef, const wxString &aValue)
Safely update a field of the associated symbol without dereferencing the symbol.
void fillSmithCursorRow(int aRow, CURSOR *aCursor, TRACE *aTrace)
const std::map< int, wxString > & UserDefinedSignals()
std::vector< wxString > m_netnames
void AddTrace(const wxString &aName, SIM_TRACE_TYPE aType)
Add a new trace to the current plot.
void onPlotClosed(wxAuiNotebookEvent &event) override
void RemoveTuner(TUNER_SLIDER *aTuner)
Remove an existing tuner.
void SaveSettings(EESCHEMA_SETTINGS *aCfg)
std::shared_ptr< SPICE_CIRCUIT_MODEL > circuitModel() const
void OnFilterText(wxCommandEvent &aEvent) override
void onMeasurementsGridCellChanged(wxGridEvent &aEvent) override
void DeleteCursor()
Deletes last m_signalsGrid "Cursor n" column, removes vector's m_cursorFormatsDyn last entry,...
void CreateNewCursor()
Creates a column at the end of m_signalsGrid named "Cursor n" ( n = m_customCursorsCnt ),...
void applyTuners()
Apply component values specified using tuner sliders to the current netlist.
bool loadJsonWorkbook(const wxString &aPath)
wxArrayString getViewChoices(SIM_PLOT_TAB *aPlotTab) const
The Signals grid's "Plot" column label for a given view ("Disabled" if null).
void clearMultiRunState(bool aClearTraces)
void OnFilterMouseMoved(wxMouseEvent &aEvent) override
void AddMeasurement(const wxString &aCmd)
Add a measurement to the measurements grid.
void onPlotChanging(wxAuiNotebookEvent &event) override
std::vector< SIM_VIEW * > getYScaleTargetViews(SIM_PLOT_TAB *aPlotTab, SIM_VIEW *aOwnView) const
The Signals grid's "Y Scale" column choices: "Default" plus one entry per eligible view.
std::map< const TUNER_SLIDER *, double > m_tunerOverrides
STD_BITMAP_BUTTON * m_addViewButton
std::shared_ptr< SPICE_SIMULATOR > simulator() const
int GetSimTabIndex(SIM_TAB *aPlot) const
STD_BITMAP_BUTTON * m_removeViewButton
void onPlotCursorUpdate(wxCommandEvent &aEvent)
void onSignalsGridCellChanged(wxGridEvent &aEvent) override
void SetCursorFormat(int aCursorId, int aValueCol, const SPICE_VALUE_FORMAT &aFormat)
void InitWorkbook()
Load the currently active workbook stored in the project settings.
void ToggleDarkModePlots()
Toggle the current S-parameter tab between Smith chart and amplitude/phase views.
SIM_TRACE_TYPE getXAxisType(SIM_TYPE aType) const
Return X axis for a given simulation type.
void signalsGridCursorUpdate(T t, U u, R r)
Updates m_signalsGrid cursor widget, column rendering and attributes.
void SetMeasureFormat(int aRow, const SPICE_VALUE_FORMAT &aFormat)
double getSmithPortImpedance(const wxString &aVectorName)
void ApplyPreferences(const SIM_PREFERENCES &aPrefs)
Called when settings are changed via the common Preferences dialog.
const SPICE_CIRCUIT_MODEL * GetExporter() const
Return the netlist exporter object used for simulations.
SIMULATOR_FRAME * m_simulatorFrame
void AddTuner(const SCH_SHEET_PATH &aSheetPath, SCH_SYMBOL *aSymbol)
Add a tuner for a symbol.
void parseTraceParams(SIM_PLOT_TAB *aPlotTab, TRACE *aTrace, const wxString &aSignalName, const wxString &aParams)
SPICE_VALUE_FORMAT GetCursorFormat(int aCursorId, int aValueCol) const
Get/Set the number of significant digits and the range for formatting a cursor value.
void OnUpdateUI(wxUpdateUIEvent &event) override
SIMULATOR_FRAME_UI(SIMULATOR_FRAME *aSimulatorFrame, SCH_EDIT_FRAME *aSchematicFrame)
SPICE_VALUE_FORMAT m_cursorFormats[3][2]
void LoadSettings(EESCHEMA_SETTINGS *aCfg)
The SIMULATOR_FRAME holds the main user-interface for running simulations.
const wxString & GetSpicePlotName() const
Definition sim_tab.h:57
SIM_TYPE GetSimType() const
Definition sim_tab.cpp:71
A single stacked plot area within a SIM_PLOT_TAB.
Special netlist exporter flavor that allows one to override simulation commands.
Storage for simulator specific settings.
A bitmap button widget that behaves like a standard dialog button except with an icon.
Overlay layer drawing the Smith chart grid (constant resistance and reactance circles)
Custom widget to handle quick component values modification and simulation on the fly.
Contains preferences pertaining to the simulator.
SIM_TRACE_TYPE
Definition sim_types.h:49
@ SPT_UNKNOWN
Definition sim_types.h:68
SIM_TYPE
< Possible simulation types
Definition sim_types.h:31
std::vector< FAB_LAYER_COLOR > dummy
std::vector< TUNER_SLIDER * > tuners
std::map< std::string, MULTI_RUN_TRACE > traces
std::vector< MULTI_RUN_STEP > steps
std::map< const TUNER_SLIDER *, double > overrides
std::vector< std::vector< double > > xRuns
std::vector< std::vector< double > > yValues
Contains preferences pertaining to the simulator.
A SPICE_VALUE_FORMAT holds precision and range info for formatting values.Helper class to handle Spic...
Definition spice_value.h:39