Plotting for noise simulations.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/2369
This commit is contained in:
parent
67c9d3932b
commit
7d3fa8fb4e
|
@ -264,17 +264,16 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i
|
|||
int m_noiseScaleNChoices = sizeof( m_noiseScaleChoices ) / sizeof( wxString );
|
||||
m_noiseScale = new wxRadioBox( m_pgNoise, wxID_ANY, _("Frequency scale"), wxDefaultPosition, wxDefaultSize, m_noiseScaleNChoices, m_noiseScaleChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_noiseScale->SetSelection( 0 );
|
||||
m_noiseScale->Hide();
|
||||
|
||||
bSizer10->Add( m_noiseScale, 0, wxALL, 5 );
|
||||
|
||||
|
||||
bSizer10->Add( 30, 0, 0, wxEXPAND, 5 );
|
||||
|
||||
wxFlexGridSizer* fgSizer11;
|
||||
fgSizer11 = new wxFlexGridSizer( 0, 3, 3, 0 );
|
||||
fgSizer11->SetFlexibleDirection( wxBOTH );
|
||||
fgSizer11->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_staticText11 = new wxStaticText( m_pgNoise, wxID_ANY, _("Number of points:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText11 = new wxStaticText( m_pgNoise, wxID_ANY, _("Number of points per decade:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText11->Wrap( -1 );
|
||||
fgSizer11->Add( m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
@ -313,7 +312,7 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i
|
|||
fgSizer11->Add( m_noiseFreqStopUnits, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
bSizer10->Add( fgSizer11, 0, wxALIGN_BOTTOM|wxBOTTOM|wxLEFT, 4 );
|
||||
bSizer10->Add( fgSizer11, 0, wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
|
||||
bSizer15->Add( bSizer10, 0, wxEXPAND|wxTOP, 5 );
|
||||
|
|
|
@ -3076,7 +3076,7 @@
|
|||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="hidden">1</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Frequency scale</property>
|
||||
<property name="majorDimension">1</property>
|
||||
|
@ -3113,17 +3113,7 @@
|
|||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="spacer" expanded="1">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">30</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">4</property>
|
||||
<property name="flag">wxALIGN_BOTTOM|wxBOTTOM|wxLEFT</property>
|
||||
<property name="flag">wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxFlexGridSizer" expanded="1">
|
||||
<property name="cols">3</property>
|
||||
|
@ -3169,7 +3159,7 @@
|
|||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Number of points:</property>
|
||||
<property name="label">Number of points per decade:</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
|
|
|
@ -329,9 +329,11 @@ wxString NGSPICE::GetXAxis( SIM_TYPE aType ) const
|
|||
switch( aType )
|
||||
{
|
||||
case ST_AC:
|
||||
case ST_NOISE:
|
||||
return wxS( "frequency" );
|
||||
|
||||
case ST_NOISE:
|
||||
return wxS( "noise1.frequency" );
|
||||
|
||||
case ST_DC:
|
||||
// find plot, which ends with "-sweep"
|
||||
for( wxString plot : AllPlots() )
|
||||
|
|
|
@ -528,13 +528,28 @@ void SIM_PLOT_PANEL::updateAxes( int aNewTraceType )
|
|||
m_axis_x->SetNameAlign( mpALIGN_BOTTOM );
|
||||
m_plotWin->AddLayer( m_axis_x );
|
||||
|
||||
m_axis_y1 = new mpScaleY( wxEmptyString, mpALIGN_LEFT, false );
|
||||
if( ( aNewTraceType & SPT_CURRENT ) == 0 )
|
||||
{
|
||||
m_axis_y1 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "" ), mpALIGN_LEFT );
|
||||
m_axis_y1->SetNameAlign( mpALIGN_LEFT );
|
||||
m_plotWin->AddLayer( m_axis_y1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_axis_y2 = new LIN_SCALE<mpScaleY>( wxEmptyString, wxT( "" ), mpALIGN_RIGHT );
|
||||
m_axis_y2->SetNameAlign( mpALIGN_RIGHT );
|
||||
m_plotWin->AddLayer( m_axis_y2 );
|
||||
}
|
||||
}
|
||||
|
||||
m_axis_x->SetName( _( "Frequency" ) );
|
||||
m_axis_y1->SetName( _( "noise [(V or A)^2/Hz]" ) );
|
||||
|
||||
if( m_axis_y1 )
|
||||
m_axis_y1->SetName( _( "Noise (V/√Hz)" ) );
|
||||
|
||||
if( m_axis_y2 )
|
||||
m_axis_y2->SetName( _( "Noise (A/√Hz)" ) );
|
||||
|
||||
break;
|
||||
|
||||
case ST_TRANSIENT:
|
||||
|
|
|
@ -59,6 +59,7 @@ bool SIM_PLOT_PANEL_BASE::IsPlottable( SIM_TYPE aSimType )
|
|||
case ST_AC:
|
||||
case ST_DC:
|
||||
case ST_TRANSIENT:
|
||||
case ST_NOISE:
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
|
|
@ -699,7 +699,8 @@ void SIMULATOR_PANEL::rebuildSignalsList()
|
|||
}
|
||||
};
|
||||
|
||||
if( options & NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES )
|
||||
if( ( options & NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES )
|
||||
&& ( simType == ST_TRANSIENT || simType == ST_DC || simType == ST_AC ) )
|
||||
{
|
||||
for( const std::string& net : circuitModel()->GetNets() )
|
||||
{
|
||||
|
@ -738,6 +739,12 @@ void SIMULATOR_PANEL::rebuildSignalsList()
|
|||
}
|
||||
}
|
||||
|
||||
if( simType == ST_NOISE )
|
||||
{
|
||||
addSignal( wxS( "inoise" ) );
|
||||
addSignal( wxS( "onoise" ) );
|
||||
}
|
||||
|
||||
// Add .PROBE directives
|
||||
for( const wxString& directive : circuitModel()->GetDirectives() )
|
||||
{
|
||||
|
@ -840,7 +847,18 @@ wxString SIMULATOR_PANEL::vectorNameFromSignalName( const wxString& aSignalName,
|
|||
|
||||
if( aTraceType )
|
||||
{
|
||||
wxUniChar firstChar = aSignalName.Upper()[0];
|
||||
wxString name = aSignalName.Upper();
|
||||
|
||||
if( name == wxS( "INOISE" ) || name == wxS( "ONOISE" ) )
|
||||
{
|
||||
if( getNoiseSource().Upper().StartsWith( 'I' ) )
|
||||
*aTraceType = SPT_CURRENT;
|
||||
else
|
||||
*aTraceType = SPT_VOLTAGE;
|
||||
}
|
||||
else if( !name.IsEmpty() )
|
||||
{
|
||||
wxUniChar firstChar = name[0];
|
||||
|
||||
if( firstChar == 'V' )
|
||||
*aTraceType = SPT_VOLTAGE;
|
||||
|
@ -849,6 +867,7 @@ wxString SIMULATOR_PANEL::vectorNameFromSignalName( const wxString& aSignalName,
|
|||
else if( firstChar == 'P' )
|
||||
*aTraceType = SPT_POWER;
|
||||
}
|
||||
}
|
||||
|
||||
wxString suffix;
|
||||
wxString name = aSignalName;
|
||||
|
@ -1432,6 +1451,10 @@ void SIMULATOR_PANEL::updateTrace( const wxString& aVectorName, int aTraceType,
|
|||
break;
|
||||
|
||||
case ST_NOISE:
|
||||
simVectorName = wxString::Format( wxS( "noise1.%s_spectrum" ), simVectorName );
|
||||
data_y = simulator()->GetMagPlot( (const char*) simVectorName.c_str() );
|
||||
break;
|
||||
|
||||
case ST_DC:
|
||||
case ST_TRANSIENT:
|
||||
data_y = simulator()->GetMagPlot( (const char*) simVectorName.c_str() );
|
||||
|
@ -2099,11 +2122,29 @@ SIM_TRACE_TYPE SIMULATOR_PANEL::getXAxisType( SIM_TYPE aType ) const
|
|||
case ST_AC: return SPT_LIN_FREQUENCY;
|
||||
case ST_DC: return SPT_SWEEP;
|
||||
case ST_TRANSIENT: return SPT_TIME;
|
||||
case ST_NOISE: return SPT_LIN_FREQUENCY;
|
||||
default: wxFAIL_MSG( wxS( "Unhandled simulation type" ) ); return SPT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wxString SIMULATOR_PANEL::getNoiseSource() const
|
||||
{
|
||||
wxString output;
|
||||
wxString ref;
|
||||
wxString source;
|
||||
wxString scale;
|
||||
SPICE_VALUE pts;
|
||||
SPICE_VALUE fStart;
|
||||
SPICE_VALUE fStop;
|
||||
|
||||
circuitModel()->ParseNoiseCommand( circuitModel()->GetSimCommand(), &output, &ref, &source,
|
||||
&scale, &pts, &fStart, &fStop );
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
void SIMULATOR_PANEL::ToggleDarkModePlots()
|
||||
{
|
||||
m_darkMode = !m_darkMode;
|
||||
|
@ -2359,6 +2400,7 @@ void SIMULATOR_PANEL::OnSimRefresh( bool aFinal )
|
|||
}
|
||||
|
||||
std::vector<wxString> oldSignals = m_signals;
|
||||
wxString msg;
|
||||
|
||||
applyUserDefinedSignals();
|
||||
rebuildSignalsList();
|
||||
|
@ -2366,6 +2408,23 @@ void SIMULATOR_PANEL::OnSimRefresh( bool aFinal )
|
|||
// If there are any signals plotted, update them
|
||||
if( SIM_PLOT_PANEL_BASE::IsPlottable( simType ) )
|
||||
{
|
||||
if( simType == ST_NOISE && aFinal )
|
||||
{
|
||||
m_simConsole->AppendText( _( "\n\nSimulation results:\n\n" ) );
|
||||
m_simConsole->SetInsertionPointEnd();
|
||||
|
||||
for( const std::string& vec : simulator()->AllPlots() )
|
||||
{
|
||||
std::vector<double> val_list = simulator()->GetRealPlot( vec, 1 );
|
||||
wxString value = SPICE_VALUE( val_list[ 0 ] ).ToSpiceString();
|
||||
|
||||
msg.Printf( wxS( "%s: %sV\n" ), vec, value );
|
||||
|
||||
m_simConsole->AppendText( msg );
|
||||
m_simConsole->SetInsertionPointEnd();
|
||||
}
|
||||
}
|
||||
|
||||
SIM_PLOT_PANEL* plotPanel = dynamic_cast<SIM_PLOT_PANEL*>( plotPanelWindow );
|
||||
wxCHECK_RET( plotPanel, wxT( "not a SIM_PLOT_PANEL" ) );
|
||||
|
||||
|
@ -2427,12 +2486,7 @@ void SIMULATOR_PANEL::OnSimRefresh( bool aFinal )
|
|||
for( const std::string& vec : simulator()->AllPlots() )
|
||||
{
|
||||
std::vector<double> val_list = simulator()->GetRealPlot( vec, 1 );
|
||||
|
||||
if( val_list.size() == 0 ) // The list of values can be empty!
|
||||
continue;
|
||||
|
||||
wxString value = SPICE_VALUE( val_list.at( 0 ) ).ToSpiceString();
|
||||
wxString msg;
|
||||
wxString value = SPICE_VALUE( val_list[ 0 ] ).ToSpiceString();
|
||||
wxString signal;
|
||||
SIM_TRACE_TYPE type = circuitModel()->VectorToSignal( vec, signal );
|
||||
|
||||
|
|
|
@ -283,6 +283,8 @@ private:
|
|||
*/
|
||||
SIM_TRACE_TYPE getXAxisType( SIM_TYPE aType ) const;
|
||||
|
||||
wxString getNoiseSource() const;
|
||||
|
||||
void parseTraceParams( SIM_PLOT_PANEL* aPlotPanel, TRACE* aTrace, const wxString& aSignalName,
|
||||
const wxString& aParams );
|
||||
|
||||
|
|
Loading…
Reference in New Issue