Update already plotted signals upon simulation run

This commit is contained in:
Maciej Suminski 2016-08-11 14:41:18 +02:00
parent 38042ac9e0
commit aea29fc730
4 changed files with 69 additions and 37 deletions

View File

@ -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
} }

View File

@ -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();

View File

@ -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 );
} }

View File

@ -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;