Update already plotted signals upon simulation run
This commit is contained in:
parent
38042ac9e0
commit
aea29fc730
|
@ -133,8 +133,6 @@ void SIM_PLOT_FRAME::StartSimulation()
|
||||||
STRING_FORMATTER formatter;
|
STRING_FORMATTER formatter;
|
||||||
|
|
||||||
m_exporter->Format( &formatter, GNL_ALL );
|
m_exporter->Format( &formatter, GNL_ALL );
|
||||||
//m_plotPanel->DeleteTraces();
|
|
||||||
|
|
||||||
m_simulator->LoadNetlist( formatter.GetString() );
|
m_simulator->LoadNetlist( formatter.GetString() );
|
||||||
|
|
||||||
// Execute the simulation in a separate thread
|
// Execute the simulation in a separate thread
|
||||||
|
@ -201,24 +199,13 @@ void SIM_PLOT_FRAME::NewPlotPanel()
|
||||||
|
|
||||||
void SIM_PLOT_FRAME::AddVoltagePlot( const wxString& aNetName )
|
void SIM_PLOT_FRAME::AddVoltagePlot( const wxString& aNetName )
|
||||||
{
|
{
|
||||||
if( !m_exporter )
|
int nodeNumber = getNodeNumber( aNetName );
|
||||||
return;
|
|
||||||
|
|
||||||
const auto& netMapping = m_exporter->GetNetIndexMap();
|
if( nodeNumber >= -1 )
|
||||||
|
{
|
||||||
if( netMapping.count( aNetName ) == 0 )
|
updatePlot( wxString::Format( "V(%d)", nodeNumber ), aNetName,
|
||||||
return;
|
static_cast<SIM_PLOT_PANEL*>( m_plotNotebook->GetCurrentPage() ) );
|
||||||
|
}
|
||||||
wxString spiceName( wxString::Format( "V(%d)", netMapping.at( aNetName ) ) );
|
|
||||||
auto data_y = m_simulator->GetPlot( (const char*) spiceName.c_str() );
|
|
||||||
|
|
||||||
if( data_y.empty() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto data_t = m_simulator->GetPlot( "time" );
|
|
||||||
|
|
||||||
SIM_PLOT_PANEL* plotPanel = static_cast<SIM_PLOT_PANEL*>( m_plotNotebook->GetCurrentPage() );
|
|
||||||
plotPanel->AddTrace( aNetName, data_t.size(), data_t.data(), data_y.data(), 0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -227,7 +214,33 @@ bool SIM_PLOT_FRAME::isSimulationRunning()
|
||||||
wxCriticalSectionLocker lock( m_simThreadCS );
|
wxCriticalSectionLocker lock( m_simThreadCS );
|
||||||
|
|
||||||
return ( m_simThread != NULL );
|
return ( m_simThread != NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SIM_PLOT_FRAME::updatePlot( const wxString& aSpiceName, const wxString& aTitle, SIM_PLOT_PANEL* aPanel )
|
||||||
|
{
|
||||||
|
auto data_y = m_simulator->GetPlot( (const char*) aSpiceName.c_str() );
|
||||||
|
auto data_t = m_simulator->GetPlot( "time" );
|
||||||
|
|
||||||
|
if( data_y.empty() || data_t.empty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
aPanel->AddTrace( aSpiceName, aTitle, data_t.size(), data_t.data(), data_y.data(), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int SIM_PLOT_FRAME::getNodeNumber( const wxString& aNetName )
|
||||||
|
{
|
||||||
|
if( !m_exporter )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const auto& netMapping = m_exporter->GetNetIndexMap();
|
||||||
|
auto it = netMapping.find( aNetName );
|
||||||
|
|
||||||
|
if( it == netMapping.end() )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -322,18 +335,12 @@ void SIM_PLOT_FRAME::onSimFinished( wxThreadEvent& aEvent )
|
||||||
m_signals->Append( net.first );
|
m_signals->Append( net.first );
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO remove?
|
// If there are any signals plotted, update them
|
||||||
#if 0
|
for( unsigned int i = 0; i < m_plotNotebook->GetPageCount(); ++i )
|
||||||
for( auto& name : m_exporter->GetProbeList() )
|
|
||||||
{
|
{
|
||||||
char spiceName[1024];
|
SIM_PLOT_PANEL* plotPanel = static_cast<SIM_PLOT_PANEL*>( m_plotNotebook->GetPage( i ) );
|
||||||
|
|
||||||
snprintf( spiceName, sizeof( spiceName ), "V(%d)", netMapping.at( name ) );
|
for( const auto& trace : plotPanel->GetTraces() )
|
||||||
//wxLogDebug( "probe %s->%s\n", (const char *) name.c_str(), spiceName );
|
updatePlot( trace.spiceName, trace.title, plotPanel );
|
||||||
// auto data_y = m_simulator->GetPlot( spiceName );
|
|
||||||
|
|
||||||
//wxLogDebug( "%d - %d data points\n", data_t.size(), data_y.size() );
|
|
||||||
// m_plotPanel->AddTrace(wxT("V(") + name + wxT(")"), data_t.size(), data_t.data(), data_y.data(), 0);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,23 @@ class SIM_PLOT_FRAME : public SIM_PLOT_FRAME_BASE
|
||||||
private:
|
private:
|
||||||
bool isSimulationRunning();
|
bool isSimulationRunning();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Updates plot in a particular SIM_PLOT_PANEL. If the panel does not contain
|
||||||
|
* the plot, it will be added.
|
||||||
|
* @param aSpiceName is the plot name in the format accepted by the current simulator instance
|
||||||
|
* (for NGSPICE it is e.g. "V(1)").
|
||||||
|
* @param aTitle is the name used in the legend.
|
||||||
|
* @param aPanel is the panel that should receive the update.
|
||||||
|
*/
|
||||||
|
void updatePlot( const wxString& aSpiceName, const wxString& aTitle, SIM_PLOT_PANEL* aPanel );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns node number for a given net.
|
||||||
|
* @param aNetName is the net number.
|
||||||
|
* @return Corresponding net number or -1 if there is no such net.
|
||||||
|
*/
|
||||||
|
int getNodeNumber( const wxString& aNetName );
|
||||||
|
|
||||||
void onNewPlot( wxCommandEvent& aEvent ) override
|
void onNewPlot( wxCommandEvent& aEvent ) override
|
||||||
{
|
{
|
||||||
NewPlotPanel();
|
NewPlotPanel();
|
||||||
|
|
|
@ -63,18 +63,19 @@ static std::pair<T, T> find_minmax( const T* aArray, unsigned int aSize )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
|
void SIM_PLOT_PANEL::AddTrace( const wxString& aSpiceName, const wxString& aTitle, int aPoints,
|
||||||
double* aT, double* aY, int aFlags )
|
double* aT, double* aY, int aFlags )
|
||||||
{
|
{
|
||||||
// Find previous entry, if there is one
|
// Find previous entry, if there is one
|
||||||
auto it = std::find_if( m_traces.begin(), m_traces.end(),
|
auto it = std::find_if( m_traces.begin(), m_traces.end(),
|
||||||
[&](const TRACE& t) { return t.name == aName; });
|
[&](const TRACE& t) { return t.title == aTitle; });
|
||||||
|
|
||||||
if( it == m_traces.end() )
|
if( it == m_traces.end() )
|
||||||
{
|
{
|
||||||
// New entry
|
// New entry
|
||||||
TRACE trace;
|
TRACE trace;
|
||||||
trace.name = aName;
|
trace.spiceName = aSpiceName;
|
||||||
|
trace.title = aTitle;
|
||||||
trace.style = wxString( '-' ) + m_painter.GenerateColor( SIM_PLOT_PAINTER::DARK );
|
trace.style = wxString( '-' ) + m_painter.GenerateColor( SIM_PLOT_PAINTER::DARK );
|
||||||
trace.x.Set( aT, aPoints );
|
trace.x.Set( aT, aPoints );
|
||||||
trace.y.Set( aY, aPoints );
|
trace.y.Set( aY, aPoints );
|
||||||
|
@ -159,7 +160,7 @@ int SIM_PLOT_PAINTER::Draw( mglGraph* aGraph )
|
||||||
// Draw traces
|
// Draw traces
|
||||||
for( auto t : traces )
|
for( auto t : traces )
|
||||||
{
|
{
|
||||||
aGraph->AddLegend( (const char*) t.name.c_str(), t.style );
|
aGraph->AddLegend( (const char*) t.title.c_str(), t.style );
|
||||||
aGraph->Plot( t.y, t.style );
|
aGraph->Plot( t.y, t.style );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,14 +64,21 @@ public:
|
||||||
|
|
||||||
~SIM_PLOT_PANEL();
|
~SIM_PLOT_PANEL();
|
||||||
|
|
||||||
struct TRACE {
|
struct TRACE
|
||||||
wxString name, style;
|
{
|
||||||
|
wxString spiceName, title, style;
|
||||||
mglData x, y;
|
mglData x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddTrace( const wxString& name, int n_points, double *t, double *x, int flags = 0 );
|
void AddTrace( const wxString& aSpiceName, const wxString& aTitle, int aPoints,
|
||||||
|
double* aT, double* aY, int aFlags );
|
||||||
void DeleteTraces();
|
void DeleteTraces();
|
||||||
|
|
||||||
|
const std::vector<TRACE>& GetTraces() const
|
||||||
|
{
|
||||||
|
return m_traces;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SIM_PLOT_PAINTER m_painter;
|
SIM_PLOT_PAINTER m_painter;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue