31#include <fmt/format.h>
32#include <wx/wfstream.h>
33#include <wx/stdstream.h>
35#include <wx/clipbrd.h>
56#include <magic_enum.hpp>
61 int res =
static_cast<int>( aFirst ) |
static_cast<int>( aSecond);
122 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
173 menu.AppendSeparator();
174 menu.Append(
MYID_FOURIER,
_(
"Perform Fourier Analysis..." ) );
177 menu.AppendSeparator();
180 menu.AppendSeparator();
183 m_grid->PopupMenu( &menu );
190 menu.AppendSeparator();
192 wxString msg =
m_grid->GetColLabelValue(
m_grid->GetNumberCols() - 1 );
194 menu.AppendSeparator();
197 m_grid->PopupMenu( &menu );
203 m_grid->PopupMenu( &menu );
210 std::vector<wxString> signals;
212 wxGridCellCoordsArray cells1 =
m_grid->GetSelectionBlockTopLeft();
213 wxGridCellCoordsArray cells2 =
m_grid->GetSelectionBlockBottomRight();
215 for(
size_t i = 0; i < cells1.Count(); i++ )
219 for(
int j = cells1[i].GetRow(); j < cells2[i].GetRow() + 1; j++ )
221 signals.push_back(
m_grid->GetCellValue( j, cells1[i].GetCol() ) );
226 wxGridCellCoordsArray cells3 =
m_grid->GetSelectedCells();
228 for(
size_t i = 0; i < cells3.Count(); i++ )
231 signals.push_back(
m_grid->GetCellValue( cells3[i].GetRow(), cells3[i].GetCol() ) );
234 if( signals.size() < 1 )
237 auto addMeasurement =
238 [
this](
const wxString& cmd, wxString signal )
240 if( signal.EndsWith(
_(
" (phase)" ) ) )
243 if( signal.EndsWith(
_(
" (gain)" ) ) || signal.EndsWith(
_(
" (amplitude)" ) ) )
245 signal = signal.Left( signal.length() - 7 );
247 if( signal.Upper().StartsWith( wxS(
"V(" ) ) )
248 signal = wxS(
"vdb" ) + signal.Mid( 1 );
256 for(
const wxString& signal : signals )
257 addMeasurement( wxS(
"MIN" ), signal );
261 for(
const wxString& signal : signals )
262 addMeasurement( wxS(
"MAX" ), signal );
266 for(
const wxString& signal : signals )
267 addMeasurement( wxS(
"AVG" ), signal );
271 for(
const wxString& signal : signals )
272 addMeasurement( wxS(
"RMS" ), signal );
276 for(
const wxString& signal : signals )
277 addMeasurement( wxS(
"PP" ), signal );
281 for(
const wxString& signal : signals )
282 addMeasurement( wxS(
"MIN_AT" ), signal );
286 for(
const wxString& signal : signals )
287 addMeasurement( wxS(
"MAX_AT" ), signal );
291 for(
const wxString& signal : signals )
292 addMeasurement( wxS(
"INTEG" ), signal );
297 wxString fundamental = wxT(
"1K" );
299 if( signals.size() == 1 )
300 title.Printf(
_(
"Fourier Analysis of %s" ), signals[0] );
302 title =
_(
"Fourier Analyses of Multiple Signals" );
312 for(
const wxString& signal : signals )
320 for(
const wxString& signal : signals )
328 if( wxTheClipboard->Open() )
330 wxTheClipboard->SetData(
new wxTextDataObject( txt ) );
331 wxTheClipboard->Flush();
332 wxTheClipboard->Close();
357 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
377 menu.AppendSeparator();
387 [
this](
int row ) -> wxString
391 if( signal.EndsWith(
"[2 - 1]" ) )
392 signal = signal.Left( signal.length() - 7 );
403 if( formatDialog.
ShowModal() == wxID_OK )
405 for(
int row = 0; row <
m_grid->GetNumberRows(); ++row )
407 if( getSignalName( row ) == getSignalName(
m_menuRow ) )
430 void showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
override;
456 menu.AppendSeparator();
469 if( formatDialog.
ShowModal() == wxID_OK )
478 std::vector<int> measurements;
480 wxGridCellCoordsArray cells1 =
m_grid->GetSelectionBlockTopLeft();
481 wxGridCellCoordsArray cells2 =
m_grid->GetSelectionBlockBottomRight();
483 for(
size_t i = 0; i < cells1.Count(); i++ )
487 for(
int j = cells1[i].GetRow(); j < cells2[i].GetRow() + 1; j++ )
488 measurements.push_back( j );
492 wxGridCellCoordsArray cells3 =
m_grid->GetSelectedCells();
494 for(
size_t i = 0; i < cells3.Count(); i++ )
497 measurements.push_back( cells3[i].GetRow() );
500 if( measurements.size() < 1 )
505 sort( measurements.begin(), measurements.end(), std::greater<>() );
507 for(
int row : measurements )
540#define ID_SIM_REFRESH 10207
541#define REFRESH_INTERVAL 50
547 m_SuppressGridEvents( 0 ),
548 m_simulatorFrame( aSimulatorFrame ),
549 m_schematicFrame( aSchematicFrame ),
567 wxGridCellAttr* attr =
new wxGridCellAttr;
571 attr =
new wxGridCellAttr;
575 attr =
new wxGridCellAttr;
579 attr =
new wxGridCellAttr;
585 attr =
new wxGridCellAttr;
595 [&]( wxTimerEvent& aEvent )
604#ifndef wxHAS_NATIVE_TABART
624 m_cursorFormat[0] = { 3, wxS(
"~s" ) };
625 m_cursorFormat[1] = { 3, wxS(
"~V" ) };
636 for(
size_t index2 = 0; index2 < std::size(
m_cursorFormats[0] ); index2++ )
652 maxCursor.Replace(
_(
"Cursor " ),
"" );
654 int tmpMax = wxAtoi( maxCursor );
656 if( nameMax < tmpMax )
666 std::vector<SPICE_VALUE_FORMAT> tmp;
678 wxGridCellAttr* attr =
new wxGridCellAttr;
698 for(
int i = 0; i < rows; i++ )
700 if(
m_signalsGrid->GetCellValue( i, col - 1 ) == wxS(
"1" ) )
703 wxGridEvent aDummy( wxID_ANY, wxEVT_GRID_CELL_CHANGED,
m_signalsGrid, i, col - 1 );
723 for(
int ii = 0; ii < static_cast<int>(
m_plotNotebook->GetPageCount() ); ++ii )
727 simTab->OnLanguageChanged();
729 wxString pageTitle(
simulator()->TypeToName( simTab->GetSimType(),
true ) );
730 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ), ii+1 ) );
751 tuner->ShowChangedLanguage();
791 simTab->ApplyPreferences( aPrefs );
798 if( !
simulator()->Settings()->GetWorkbookFilename().IsEmpty() )
800 wxFileName filename =
simulator()->Settings()->GetWorkbookFilename();
804 simulator()->Settings()->SetWorkbookFilename(
"" );
808 wxString schTextSimCommand =
circuitModel()->GetSchTextSimCommand();
810 if( !schTextSimCommand.IsEmpty() )
843 std::sort( signals.begin(), signals.end(),
844 [](
const wxString& lhs,
const wxString& rhs )
847 if( lhs.Upper().StartsWith(
'V' ) && !rhs.Upper().StartsWith(
'V' ) )
849 else if( !lhs.Upper().StartsWith(
'V' ) && rhs.Upper().StartsWith(
'V' ) )
852 return StrNumCmp( lhs, rhs, true ) < 0;
869 std::vector<wxString> signals;
873 wxStringTokenizer tokenizer( plotPanel->
GetSimCommand(), wxT(
" \t\r\n" ), wxTOKEN_STRTOK );
875 while( tokenizer.HasMoreTokens() && tokenizer.GetNextToken().Lower() != wxT(
"fft" ) )
878 while( tokenizer.HasMoreTokens() )
879 signals.emplace_back( tokenizer.GetNextToken() );
886 for(
const wxString& signal :
m_signals )
887 signals.push_back( signal );
891 if( simType ==
ST_AC )
893 signals.push_back( signal +
_(
" (gain)" ) );
894 signals.push_back( signal +
_(
" (phase)" ) );
896 else if( simType ==
ST_SP )
898 signals.push_back( signal +
_(
" (amplitude)" ) );
899 signals.push_back( signal +
_(
" (phase)" ) );
903 signals.push_back( signal );
910 if( aFilter.IsEmpty() )
911 aFilter = wxS(
"*" );
916 for(
const wxString& signal : signals )
918 if( matcher.
Find( signal.Upper() ) )
927 wxGridCellAttr* attr =
new wxGridCellAttr;
928 attr->SetRenderer(
new wxGridCellBoolRenderer() );
930 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
935 attr =
new wxGridCellAttr;
940 attr =
new wxGridCellAttr;
944 attr =
new wxGridCellAttr;
952 attr =
new wxGridCellAttr;
962 attr =
new wxGridCellAttr;
965 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
970 attr =
new wxGridCellAttr;
971 attr->SetRenderer(
new wxGridCellBoolRenderer() );
973 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
977 attr =
new wxGridCellAttr;
978 attr->SetRenderer(
new wxGridCellBoolRenderer() );
980 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
988 attr =
new wxGridCellAttr;
989 attr->SetRenderer(
new wxGridCellBoolRenderer() );
991 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
1010 wxString unconnected = wxString( wxS(
"unconnected-(" ) );
1015 unconnected.Replace(
'(',
'_' );
1018 [&](
const wxString& aSignalName )
1020 if( simType ==
ST_AC )
1022 m_signals.push_back( aSignalName +
_(
" (gain)" ) );
1023 m_signals.push_back( aSignalName +
_(
" (phase)" ) );
1025 else if( simType ==
ST_SP )
1027 m_signals.push_back( aSignalName +
_(
" (amplitude)" ) );
1028 m_signals.push_back( aSignalName +
_(
" (phase)" ) );
1045 if( netname ==
"GND" || netname ==
"0" || netname.StartsWith( unconnected ) )
1049 addSignal( wxString::Format( wxS(
"V(%s)" ), netname ) );
1059 for(
const std::string&
name : item.model->SpiceGenerator().CurrentNames( item ) )
1069 if( item.model->GetPinCount() >= 2 )
1071 wxString
name = item.model->SpiceGenerator().ItemName( item );
1072 addSignal( wxString::Format( wxS(
"P(%s)" ),
name ) );
1079 addSignal( wxS(
"inoise_spectrum" ) );
1080 addSignal( wxS(
"onoise_spectrum" ) );
1083 if( simType ==
ST_SP )
1085 std::vector<std::string> portnums;
1089 wxString
name = item.model->SpiceGenerator().ItemName( item );
1092 if( !
name.StartsWith(
"V" ) )
1095 std::string portnum =
"";
1097 if(
const SIM_MODEL::PARAM* portnum_param = item.model->FindParam(
"portnum" ) )
1101 portnums.push_back( portnum );
1104 for(
const std::string& portnum1 : portnums )
1106 for(
const std::string& portnum2 : portnums )
1108 addSignal( wxString::Format( wxS(
"S_%s_%s" ), portnum1, portnum2 ) );
1114 for(
const wxString& directive :
circuitModel()->GetDirectives() )
1116 wxStringTokenizer directivesTokenizer( directive, wxT(
"\r\n" ), wxTOKEN_STRTOK );
1118 while( directivesTokenizer.HasMoreTokens() )
1120 wxString line = directivesTokenizer.GetNextToken().Upper();
1121 wxString directiveParams;
1123 if( line.StartsWith( wxS(
".SAVE" ), &directiveParams )
1124 || line.StartsWith( wxS(
".PROBE" ), &directiveParams ) )
1126 wxStringTokenizer paramsTokenizer( directiveParams, wxT(
" \t" ), wxTOKEN_STRTOK );
1128 while( paramsTokenizer.HasMoreTokens() )
1129 addSignal( paramsTokenizer.GetNextToken() );
1152 wxString pageTitle(
simulator()->TypeToName( simType,
true ) );
1153 pageTitle.Prepend( wxString::Format(
_(
"Analysis %u - " ),
static_cast<unsigned int>( ++
m_plotNumber ) ) );
1169 wxPoint pos = aEvent.GetPosition();
1170 wxRect ctrlRect =
m_filter->GetScreenRect();
1171 int buttonWidth = ctrlRect.GetHeight();
1173 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
1174 SetCursor( wxCURSOR_ARROW );
1175 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
1176 SetCursor( wxCURSOR_ARROW );
1178 SetCursor( wxCURSOR_IBEAM );
1184 return wxString::Format( wxS(
"user%d" ), aUserDefinedSignalId );
1193 const wxString& aSignalName,
1196 std::map<wxString, int> suffixes;
1212 wxUniChar firstChar = aSignalName.Upper()[0];
1214 if( firstChar ==
'V' )
1216 else if( firstChar ==
'I' )
1218 else if( firstChar ==
'P' )
1223 wxString
name = aSignalName;
1225 for(
const auto& [ candidate, type ] : suffixes )
1227 if(
name.EndsWith( candidate ) )
1229 name =
name.Left(
name.Length() - candidate.Length() );
1232 *aTraceType |= type;
1240 if(
name == signal )
1258 int row = aEvent.GetRow();
1259 int col = aEvent.GetCol();
1267 if(
text == wxS(
"1" ) )
1303 TRACE* activeTrace =
nullptr;
1305 if(
text == wxS(
"1" ) )
1309 activeTrace = plotTab->
GetTrace( vectorName, traceType );
1320 if( trace != activeTrace && trace->
HasCursor(
id ) )
1343 int row = aEvent.GetRow();
1344 int col = aEvent.GetCol();
1352 CURSOR* cursor1 =
nullptr;
1353 CURSOR* cursor2 =
nullptr;
1355 std::vector<CURSOR*> cursorsVec;
1377 cursorsVec.emplace_back(
cursor );
1379 if( cursorName == ( wxString(
"" ) << i ) &&
cursor )
1380 cursor->SetCoordX( value );
1387 if( cursorName == wxS(
"1" ) && cursor1 )
1389 else if( cursorName == wxS(
"2" ) && cursor2 )
1391 else if( cursorName ==
_(
"Diff" ) && cursor1 && cursor2 )
1399 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1432 int row = aEvent.GetRow();
1433 int col = aEvent.GetCol();
1443 wxFAIL_MSG( wxT(
"All other columns are supposed to be read-only!" ) );
1451 for( row = rowCount - 1; row >= 0; row-- )
1461 int killRows = emptyRows - 1;
1464 else if( emptyRows == 0 )
1475 if( plotTab->GetLegendPosition() != plotTab->m_LastLegendPosition )
1477 plotTab->m_LastLegendPosition = plotTab->GetLegendPosition();
1500 static wxRegEx measureParamsRegEx( wxT(
"^"
1504 "([a-zA-Z]*)\\(([^\\)]+)\\)" ) );
1513 if(
text.IsEmpty() )
1520 wxString resultName = wxString::Format( wxS(
"meas_result_%u" ), aRow );
1521 wxString result = wxS(
"?" );
1523 if( measureParamsRegEx.Matches(
text ) )
1525 wxString func = measureParamsRegEx.GetMatch(
text, 1 ).Upper();
1526 wxString signalType = measureParamsRegEx.GetMatch(
text, 2 ).Upper();
1527 wxString deviceName = measureParamsRegEx.GetMatch(
text, 3 );
1531 if( signalType.EndsWith( wxS(
"DB" ) ) )
1533 units = wxS(
"dB" );
1535 else if( signalType.StartsWith(
'I' ) )
1539 else if( signalType.StartsWith(
'P' ) )
1543 text = func +
" " + deviceName +
":power";
1550 if( func.EndsWith( wxS(
"_AT" ) ) )
1553 units = wxS(
"Hz" );
1557 else if( func.StartsWith( wxS(
"INTEG" ) ) )
1562 if ( signalType.StartsWith(
'P' ) )
1565 units += wxS(
".s" );
1575 units += wxS(
"·Hz" );
1583 units += wxS(
"·?" );
1596 wxString cmd = wxString::Format( wxS(
"meas %s %s %s" ), simType, resultName,
text );
1597 simulator()->Command(
"echo " + cmd.ToStdString() );
1598 simulator()->Command( cmd.ToStdString() );
1600 std::vector<double> resultVec =
simulator()->GetGainVector( resultName.ToStdString() );
1602 if( resultVec.size() > 0 )
1617 "the value of a passive R, L, C model or voltage or "
1618 "current source." ) );
1622 wxString ref = aSymbol->
GetRef( &aSheetPath );
1627 if( tuner->GetSymbolRef() == ref )
1650 const wxString& aRef,
const wxString& aValue )
1658 + wxString::Format(
_(
"%s not found" ), aRef ) );
1665 std::vector<EMBEDDED_FILES*> embeddedFilesStack;
1678 + wxString::Format(
_(
"%s is not tunable" ), aRef ) );
1743 wxString cmd = wxString::Format( wxS(
"fourier %s %s" ),
1747 simulator()->Command( cmd.ToStdString() );
1761 m_simConsole->AppendText(
_(
"Error: no current simulation.\n" ) );
1770 m_simConsole->AppendText(
_(
"Error: simulation type not defined.\n" ) );
1776 m_simConsole->AppendText(
_(
"Error: simulation type doesn't support plotting.\n" ) );
1783 if( simType ==
ST_AC )
1788 else if( simType ==
ST_SP )
1798 plotTab->GetPlotWin()->UpdateAll();
1820 if( aNewSignals.count(
id ) == 0 )
1825 plotTab->
DeleteTrace( vectorName, traceType | subType );
1830 plotTab->
DeleteTrace( vectorName, traceType | subType );
1843 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1844 trace->SetName( aNewSignals.at(
id ) );
1851 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType | subType ) )
1852 trace->SetName( aNewSignals.at(
id ) );
1857 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
1858 trace->SetName( aNewSignals.at(
id ) );
1892 wxString simVectorName = aVectorName;
1895 simVectorName = simVectorName.AfterFirst(
'(' ).BeforeLast(
')' ) + wxS(
":power" );
1900 simulator()->Command( wxString::Format( wxT(
"print %s" ), aVectorName ).ToStdString() );
1905 std::vector<double> data_x;
1906 std::vector<double> data_y;
1908 if( !aDataX || aClearData )
1912 if( aDataX->empty() && !aClearData )
1914 wxString xAxisName(
simulator()->GetXAxis( simType ) );
1916 if( xAxisName.IsEmpty() )
1919 *aDataX =
simulator()->GetGainVector( (
const char*) xAxisName.c_str() );
1922 unsigned int size = aDataX->size();
1928 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1930 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1932 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or AC_MAG bit" ) );
1937 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1939 data_y =
simulator()->GetPhaseVector( (
const char*) simVectorName.c_str(), size );
1941 wxFAIL_MSG( wxT(
"Plot type missing AC_PHASE or SPT_SP_AMP bit" ) );
1946 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), -1 );
1952 data_y =
simulator()->GetGainVector( (
const char*) simVectorName.c_str(), size );
1956 wxFAIL_MSG( wxT(
"Unhandled plot type" ) );
1961 size_t sweepSize = std::numeric_limits<size_t>::max();
1963 if( simType ==
ST_DC
1970 sweepSize = aDataX->size() / sweepCount;
1975 if( data_y.size() >= size )
1976 aPlotTab->
SetTraceData( trace, *aDataX, data_y, sweepCount, sweepSize );
1983template void SIMULATOR_FRAME_UI::signalsGridCursorUpdate<SIGNALS_GRID_COLUMNS, int, int>(
1986template <
typename T,
typename U,
typename R>
1995 wxGridCellAttrPtr attr =
m_signalsGrid->GetOrCreateCellAttrPtr( r,
static_cast<int>( t ) );
1997 if(
TRACE* trace = plotTab ? plotTab->
GetTrace( vectorName, traceType ) :
nullptr )
1999 attr->SetReadOnly();
2001 if( t >= SIGNALS_GRID_COLUMNS::COL_SIGNAL_SHOW )
2003 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
2006 if constexpr ( std::is_enum<T>::value )
2008 if( t == SIGNALS_GRID_COLUMNS::COL_SIGNAL_SHOW )
2010 m_signalsGrid->SetCellValue( r,
static_cast<int>( t ), wxS(
"1" ) );
2012 else if( t == SIGNALS_GRID_COLUMNS::COL_SIGNAL_COLOR )
2014 if( !attr->HasRenderer() )
2017 if( !attr->HasEditor() )
2020 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
2021 attr->SetReadOnly(
false );
2026 else if( t == SIGNALS_GRID_COLUMNS::COL_CURSOR_1
2027 || t == SIGNALS_GRID_COLUMNS::COL_CURSOR_2
2028 || t > SIGNALS_GRID_COLUMNS::COL_CURSOR_2 )
2030 if( !attr->HasRenderer() )
2031 attr->SetRenderer(
new wxGridCellBoolRenderer() );
2033 if( u > 0 && trace->HasCursor( u ) )
2034 m_signalsGrid->SetCellValue( r,
static_cast<int>( t ), wxS(
"1" ) );
2036 m_signalsGrid->SetCellValue( r,
static_cast<int>( t ), wxEmptyString );
2042 if constexpr ( std::is_enum<T>::value )
2044 if( t == SIGNALS_GRID_COLUMNS::COL_SIGNAL_SHOW )
2046 m_signalsGrid->SetCellValue( r,
static_cast<int>( t ), wxEmptyString );
2048 else if( t == SIGNALS_GRID_COLUMNS::COL_SIGNAL_COLOR
2049 || t == SIGNALS_GRID_COLUMNS::COL_CURSOR_1
2050 || t == SIGNALS_GRID_COLUMNS::COL_CURSOR_2
2051 || t > SIGNALS_GRID_COLUMNS::COL_CURSOR_2 )
2053 attr->SetEditor(
nullptr );
2054 attr->SetRenderer(
nullptr );
2055 attr->SetReadOnly();
2056 m_signalsGrid->SetCellValue( r,
static_cast<int>( t ), wxEmptyString );
2065 for(
int row = 0; row <
m_signalsGrid->GetNumberRows(); ++row )
2090 auto quoteNetNames = [&]( wxString aExpression ) -> wxString
2092 std::vector<bool> mask( aExpression.length(),
false );
2096 size_t pos = aExpression.find( netname );
2098 while( pos != wxString::npos )
2100 for(
size_t i = 0; i < netname.length(); ++i )
2102 mask[pos + i] =
true;
2104 pos = aExpression.find( netname, pos + 1 );
2108 wxString quotedNetnames =
"";
2109 bool startQuote =
true;
2112 for(
size_t i = 0; i < aExpression.length(); i++ )
2114 if( mask[i] && startQuote )
2116 quotedNetnames = quotedNetnames +
"\"";
2119 else if( !mask[i] && !startQuote )
2121 quotedNetnames = quotedNetnames +
"\"";
2124 wxString ch = aExpression[i];
2125 quotedNetnames = quotedNetnames + ch;
2130 quotedNetnames = quotedNetnames +
"\"";
2132 return quotedNetnames;
2137 constexpr const char* cmd =
"let user{} = {}";
2139 simulator()->Command(
"echo " + fmt::format( cmd,
id, signal.ToStdString() ) );
2140 simulator()->Command( fmt::format( cmd,
id, quoteNetNames( signal ).ToStdString() ) );
2152 wxString ref = tuner->GetSymbolRef();
2153 KIID symbolId = tuner->GetSymbol( &sheetPath );
2159 reporter.
Report( wxString::Format(
_(
"%s not found" ), ref ) );
2167 reporter.
Report( wxString::Format(
_(
"%s is not tunable" ), ref ) );
2171 double floatVal = tuner->GetValue().ToDouble();
2183 wxTextFile file( aPath );
2188 wxString firstLine = file.GetFirstLine();
2190 bool legacy = firstLine.StartsWith( wxT(
"version " ) ) || firstLine.ToLong( &
dummy );
2215 wxFileName filename( aPath );
2219 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
2227 wxFFileInputStream fp( aPath, wxT(
"rt" ) );
2228 wxStdInputStream fstream( fp );
2235 nlohmann::json js = nlohmann::json::parse( fstream,
nullptr,
true,
true );
2237 std::map<SIM_PLOT_TAB*, nlohmann::json> traceInfo;
2239 for(
const nlohmann::json& tab_js : js[
"tabs" ] )
2241 wxString simCommand;
2245 for(
const nlohmann::json& cmd : tab_js[
"commands" ] )
2247 if( cmd ==
".kicad adjustpaths" )
2249 else if( cmd ==
".save all" )
2251 else if( cmd ==
".probe alli" )
2253 else if( cmd ==
".probe allp" )
2255 else if( cmd ==
".kicad esavenone" )
2258 simCommand += wxString( cmd.get<wxString>() ).Trim();
2268 if( tab_js.contains(
"traces" ) )
2269 traceInfo[plotTab] = tab_js[
"traces" ];
2271 if( tab_js.contains(
"measurements" ) )
2273 for(
const nlohmann::json& m_js : tab_js[
"measurements" ] )
2274 plotTab->
Measurements().emplace_back( m_js[
"expr" ], m_js[
"format" ] );
2278 plotTab->
ShowGrid( tab_js[
"showGrid" ] );
2280 if( tab_js.contains(
"fixedY1scale" ) )
2282 const nlohmann::json& scale_js = tab_js[
"fixedY1scale" ];
2283 plotTab->
SetY1Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2287 if( tab_js.contains(
"fixedY2scale" ) )
2289 const nlohmann::json& scale_js = tab_js[
"fixedY2scale" ];
2290 plotTab->
SetY2Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2294 if( tab_js.contains(
"fixedY3scale" ) )
2297 const nlohmann::json& scale_js = tab_js[
"fixedY3scale" ];
2298 plotTab->
SetY3Scale(
true, scale_js[
"min" ], scale_js[
"max" ] );
2302 if( tab_js.contains(
"legend" ) )
2304 const nlohmann::json& legend_js = tab_js[
"legend" ];
2309 if( tab_js.contains(
"margins" ) )
2311 const nlohmann::json& margins_js = tab_js[
"margins" ];
2313 margins_js[
"right" ],
2314 margins_js[
"bottom" ],
2315 margins_js[
"left" ] );
2322 if( js.contains(
"user_defined_signals" ) )
2324 for(
const nlohmann::json& signal_js : js[
"user_defined_signals" ] )
2333 firstTab->SetLastSchTextSimCommand( js[
"last_sch_text_sim_command"] );
2336 int tempCustomCursorsCnt = 0;
2338 if( js.contains(
"custom_cursors" ) )
2339 tempCustomCursorsCnt = js[
"custom_cursors"];
2341 tempCustomCursorsCnt = 2;
2351 int aCursorId,
const nlohmann::json& aCursor_js )
2353 if( aCursorId >= 1 )
2357 cursor->SetName( aSignalName );
2358 cursor->SetCoordX( aCursor_js[
"position" ] );
2360 aTrace->SetCursor( aCursorId,
cursor );
2364 if( aCursorId == -1 )
2375 aCursor_js[
"x_format"] );
2377 aCursor_js[
"y_format"] );
2387 for(
const auto& [ plotTab, traces_js ] : traceInfo )
2389 for(
const nlohmann::json& trace_js : traces_js )
2391 wxString signalName = trace_js[
"signal" ];
2393 TRACE* trace = plotTab->GetOrAddTrace( vectorName, trace_js[
"trace_type" ] );
2397 if( trace_js.contains(
"cursorD" ) )
2398 addCursor( plotTab, trace, signalName, -1, trace_js[
"cursorD" ] );
2400 std::vector<const char*> aVec;
2403 for(
int i = 1; i <= tempCustomCursorsCnt; i++ )
2405 wxString str =
"cursor" + std::to_string( i );
2406 aVec.emplace_back( str.c_str() );
2408 if( trace_js.contains( aVec[i - 1] ) )
2409 addCursor( plotTab, trace, signalName, i, trace_js[aVec[i - 1]] );
2412 if( trace_js.contains(
"color" ) )
2415 color.Set( wxString( trace_js[
"color"].get<wxString>() ) );
2417 plotTab->UpdateTraceStyle( trace );
2422 plotTab->UpdatePlotColors();
2425 catch( nlohmann::json::parse_error& error )
2427 wxLogTrace(
traceSettings, wxT(
"Json parse error reading %s: %s" ), aPath, error.what() );
2431 catch( nlohmann::json::type_error& error )
2433 wxLogTrace(
traceSettings, wxT(
"Json type error reading %s: %s" ), aPath, error.what() );
2437 catch( nlohmann::json::invalid_iterator& error )
2439 wxLogTrace(
traceSettings, wxT(
"Json invalid_iterator error reading %s: %s" ), aPath, error.what() );
2443 catch( nlohmann::json::out_of_range& error )
2445 wxLogTrace(
traceSettings, wxT(
"Json out_of_range error reading %s: %s" ), aPath, error.what() );
2451 wxLogTrace(
traceSettings, wxT(
"Error reading %s" ), aPath );
2460 int cursorIdAfterD = aCursorId;
2463 cursorIdAfterD = cursorIdAfterD - 1;
2468 aTraceJs[
"cursor" + wxString(
"" ) << aCursorId] =
2469 nlohmann::json( { {
"position",
cursor->GetCoords().x },
2476 aTraceJs[
"cursorD"] =
2487 wxFileName filename = aPath;
2492 file.Create( filename.GetFullPath(),
true );
2494 if( !file.IsOpened() )
2497 nlohmann::json tabs_js = nlohmann::json::array();
2508 nlohmann::json commands_js = nlohmann::json::array();
2515 commands_js.push_back(
".kicad adjustpaths" );
2518 commands_js.push_back(
".save all" );
2521 commands_js.push_back(
".probe alli" );
2524 commands_js.push_back(
".probe allp" );
2527 commands_js.push_back(
".kicad esavenone" );
2529 nlohmann::json tab_js = nlohmann::json(
2531 {
"commands", commands_js } } );
2535 nlohmann::json traces_js = nlohmann::json::array();
2537 auto findSignalName =
2538 [&](
const wxString& aVectorName ) -> wxString
2540 wxString vectorName;
2543 if( aVectorName.EndsWith(
_(
" (phase)" ) ) )
2544 suffix =
_(
" (phase)" );
2545 else if( aVectorName.EndsWith(
_(
" (gain)" ) ) )
2546 suffix =
_(
" (gain)" );
2548 vectorName = aVectorName.Left( aVectorName.Length() - suffix.Length() );
2553 return signal + suffix;
2559 for(
const auto& [
name, trace] : plotTab->GetTraces() )
2561 nlohmann::json trace_js = nlohmann::json(
2562 { {
"trace_type", (int) trace->GetType() },
2563 {
"signal", findSignalName( trace->GetDisplayName() ) },
2569 if( trace->GetCursor( 1 ) || trace->GetCursor( 2 ) )
2571 trace_js[
"cursorD"] = nlohmann::json(
2576 traces_js.push_back( trace_js );
2579 nlohmann::json measurements_js = nlohmann::json::array();
2581 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2583 measurements_js.push_back( nlohmann::json( { {
"expr",
measurement },
2584 {
"format", format } } ) );
2587 tab_js[
"traces" ] = traces_js;
2588 tab_js[
"measurements" ] = measurements_js;
2589 tab_js[
"dottedSecondary" ] = plotTab->GetDottedSecondary();
2590 tab_js[
"showGrid" ] = plotTab->IsGridShown();
2594 if( plotTab->GetY1Scale( &min, &max ) )
2595 tab_js[
"fixedY1scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2597 if( plotTab->GetY2Scale( &min, &max ) )
2598 tab_js[
"fixedY2scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2600 if( plotTab->GetY3Scale( &min, &max ) )
2601 tab_js[
"fixedY3scale" ] = nlohmann::json( { {
"min", min }, {
"max", max } } );
2603 if( plotTab->IsLegendShown() )
2605 tab_js[
"legend" ] = nlohmann::json( { {
"x", plotTab->GetLegendPosition().x },
2606 {
"y", plotTab->GetLegendPosition().y } } );
2609 mpWindow* plotWin = plotTab->GetPlotWin();
2611 tab_js[
"margins" ] = nlohmann::json( { {
"left", plotWin->
GetMarginLeft() },
2617 tabs_js.push_back( tab_js );
2620 nlohmann::json userDefinedSignals_js = nlohmann::json::array();
2623 userDefinedSignals_js.push_back( signal );
2626 nlohmann::json js = nlohmann::json( { {
"version", 7 },
2627 {
"tabs", tabs_js },
2628 {
"user_defined_signals", userDefinedSignals_js },
2641 std::stringstream buffer;
2642 buffer << std::setw( 2 ) << js << std::endl;
2644 bool res = file.Write( buffer.str() );
2651 simulator()->Settings()->SetWorkbookFilename( filename.GetFullPath() );
2671 wxFAIL_MSG( wxString::Format( wxS(
"Unhandled simulation type: %d" ), (
int) aType ) );
2691 &source, &
scale, &pts, &fStart, &fStop, &saveAll );
2699 int& aSashPosition )
2701 bool isShown = aPanel->IsShown();
2704 aSashPosition = aSplitterWindow->GetSashPosition();
2706 aPanel->Show( !isShown );
2708 aSplitterWindow->SetSashInvisible( isShown );
2709 aSplitterWindow->SetSashPosition( isShown ? -1 : aSashPosition,
true );
2711 aSplitterWindow->UpdateSize();
2712 m_parent->Refresh();
2749 for(
size_t page = 0; page <
m_plotNotebook->GetPageCount(); page++ )
2794 std::vector<std::pair<wxString, wxString>>& measurements = plotTab->Measurements();
2796 measurements.clear();
2834 simulator()->Command(
"setplot " + simTab->GetSpicePlotName().ToStdString() );
2848 for(
const auto& [
measurement, format ] : plotTab->Measurements() )
2856 if( plotTab->GetSimType() ==
ST_TRAN || plotTab->GetSimType() ==
ST_AC
2857 || plotTab->GetSimType() ==
ST_DC || plotTab->GetSimType() ==
ST_SP )
2894 CURSOR* cursor1 =
nullptr;
2895 wxString cursor1Name;
2896 wxString cursor1Units;
2897 CURSOR* cursor2 =
nullptr;
2898 wxString cursor2Name;
2899 wxString cursor2Units;
2902 [&](
TRACE* aTrace ) -> wxString
2923 [&](
TRACE* aTrace ) -> wxString
2944 [
this](
double aValue,
int aCursorId,
int aCol ) -> wxString
2957 cursor1Name = getNameY( trace );
2958 cursor1Units = getUnitsY( trace );
2960 wxRealPoint coords =
cursor->GetCoords();
2980 cursor2Name = getNameY( trace );
2981 cursor2Units = getUnitsY( trace );
2983 wxRealPoint coords =
cursor->GetCoords();
2998 if( cursor1 && cursor2 && cursor1Units == cursor2Units )
3007 signal = wxString::Format( wxS(
"%s[2 - 1]" ), cursor2->
GetName() );
3009 signal = wxString::Format( wxS(
"%s - %s" ), cursor2->
GetName(), cursor1->
GetName() );
3020 wxString valColName =
_(
"Value" );
3022 if( !cursor1Name.IsEmpty() )
3024 if( cursor2Name.IsEmpty() || cursor1Name == cursor2Name )
3025 valColName = cursor1Name;
3027 else if( !cursor2Name.IsEmpty() )
3029 valColName = cursor2Name;
3043 wxString cursName = getNameY( trace );
3044 wxString cursUnits = getUnitsY( trace );
3046 wxRealPoint coords =
cursor->GetCoords();
3061 valColName =
_(
"Value" );
3063 if( !cursName.IsEmpty()
3066 valColName = cursName;
3087 plotTab->ResetScales(
true );
3107 std::vector<wxString> signals;
3109 for(
const std::string& vec :
simulator()->AllVectors() )
3110 signals.emplace_back( vec );
3118 std::vector<wxString> signals;
3120 for(
const wxString& signal :
m_signals )
3121 signals.emplace_back( signal );
3124 signals.emplace_back( signal );
3156 if( simType ==
ST_NOISE && aFinal )
3158 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
3165 simulator()->CurrentPlotName().Mid( 5 ).ToLong( &number );
3167 for(
const std::string& vec :
simulator()->AllVectors() )
3169 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
3172 msg.Printf( wxS(
"%s: %sV\n" ), vec, value );
3178 simulator()->Command( fmt::format(
"setplot noise{}", number - 1 ) );
3183 wxCHECK_RET( plotTab, wxString::Format( wxT(
"No SIM_PLOT_TAB for: %s" ),
3184 magic_enum::enum_name( simType ) ) );
3193 std::map<TRACE*, TRACE_INFO> traceMap;
3196 traceMap[ trace ] = { wxEmptyString,
SPT_UNKNOWN,
false };
3201 for(
const wxString& signal :
m_signals )
3206 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
3207 traceMap[ trace ] = { vectorName, traceType,
false };
3215 if( simType ==
ST_AC )
3221 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
3222 traceMap[ trace ] = { vectorName, subType, !aFinal };
3225 else if( simType ==
ST_SP )
3231 if(
TRACE* trace = plotTab->
GetTrace( vectorName, subType ) )
3232 traceMap[trace] = { vectorName, subType, !aFinal };
3237 if(
TRACE* trace = plotTab->
GetTrace( vectorName, traceType ) )
3238 traceMap[ trace ] = { vectorName, traceType, !aFinal };
3244 for(
const auto& [ trace, traceInfo ] : traceMap )
3246 if( traceInfo.Vector.IsEmpty() )
3250 for(
const auto& [ trace,
info ] : traceMap )
3252 std::vector<double> data_x;
3254 if( !
info.Vector.IsEmpty() )
3272 else if( simType ==
ST_OP && aFinal )
3274 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
3277 for(
const std::string& vec :
simulator()->AllVectors() )
3279 std::vector<double> val_list =
simulator()->GetRealVector( vec, 1 );
3281 if( val_list.empty() )
3288 const size_t tab = 25;
3289 size_t padding = ( signal.length() < tab ) ? ( tab - signal.length() ) : 1;
3293 case SPT_VOLTAGE: value.Append( wxS(
"V" ) );
break;
3294 case SPT_CURRENT: value.Append( wxS(
"A" ) );
break;
3295 case SPT_POWER: value.Append( wxS(
"W" ) );
break;
3296 default: value.Append( wxS(
"?" ) );
break;
3299 msg.Printf( wxT(
"%s%s\n" ),
3300 ( signal + wxT(
":" ) ).Pad( padding, wxUniChar(
' ' ) ),
3307 signal = signal.SubString( 2, signal.Length() - 2 );
3310 signal += wxS(
":power" );
3315 else if( simType ==
ST_PZ && aFinal )
3317 m_simConsole->AppendText(
_(
"\n\nSimulation results:\n\n" ) );
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
void doPopupSelection(wxCommandEvent &event) override
SIMULATOR_FRAME_UI * m_parent
CURSORS_GRID_TRICKS(SIMULATOR_FRAME_UI *aParent, WX_GRID *aGrid)
The SIMULATOR_FRAME holds the main user-interface for running simulations.
const wxRealPoint & GetCoords() const
void SetCoordX(double aValue)
bool Find(const wxString &aTerm, int &aMatchersTriggered, int &aPosition)
Look in all existing matchers, return the earliest match of any of the existing.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
virtual void doPopupSelection(wxCommandEvent &event)
virtual void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent)
WX_GRID * m_grid
I don't own the grid, but he owns me.
A color representation with 4 components: red, green, blue, alpha.
wxString ToCSSString() const
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Hold a translatable error message and may be used when throwing exceptions containing a translated er...
const wxString What() const
void doPopupSelection(wxCommandEvent &event) override
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
SIMULATOR_FRAME_UI * m_parent
MEASUREMENTS_GRID_TRICKS(SIMULATOR_FRAME_UI *aParent, WX_GRID *aGrid)
static void ConvertToSpiceMarkup(wxString *aNetName)
Remove formatting wrappers and replace illegal spice net name characters with underscores.
@ OPTION_SAVE_ALL_CURRENTS
@ OPTION_SAVE_ALL_VOLTAGES
@ OPTION_SAVE_ALL_DISSIPATIONS
@ OPTION_ADJUST_INCLUDE_PATHS
@ OPTION_ADJUST_PASSIVE_VALS
const SPICE_ITEM * FindItem(const wxString &aRefName) const
Find and return the item corresponding to aRefName.
A singleton reporter that reports to nowhere.
virtual const wxString GetProjectPath() const
Return the full path of the project.
Holds all the data relating to one schematic.
void SetOperatingPoint(const wxString &aSignal, double aValue)
Set operating points from a .op simulation.
void ClearOperatingPoints()
Clear operating points from a .op simulation.
EMBEDDED_FILES * GetEmbeddedFiles() override
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
EESCHEMA_SETTINGS * eeconfig() const
Schematic editor (Eeschema) main window.
void RefreshOperatingPointDisplay()
Refresh the display of any operating points.
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
SCHEMATIC & Schematic() const
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false) override
Mark an item for refresh.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_ITEM * ResolveItem(const KIID &aID) const
Fetch a SCH_ITEM by ID.
EMBEDDED_FILES * GetEmbeddedFiles() override
SCH_SYMBOLs don't currently support embedded files, but their LIB_SYMBOL counterparts do.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
void doPopupSelection(wxCommandEvent &event) override
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
SIMULATOR_FRAME_UI * m_parent
SIGNALS_GRID_TRICKS(SIMULATOR_FRAME_UI *aParent, WX_GRID *aGrid)
Class SIMULATOR_FRAME_UI_BASE.
wxBoxSizer * m_sizerTuners
WX_GRID * m_measurementsGrid
wxSplitterWindow * m_splitterLeftRight
wxSplitterWindow * m_splitterMeasurements
wxTextCtrl * m_simConsole
wxSplitterWindow * m_splitterCursors
wxSplitterWindow * m_splitterPlotAndConsole
wxSplitterWindow * m_splitterSignals
wxAuiNotebook * m_plotNotebook
The SIMULATOR_FRAME_UI holds the main user-interface for running simulations.
SIM_TAB * NewSimTab(const wxString &aSimCommand)
Create a new simulation tab for a given simulation type.
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.
int m_splitterTuneValuesSashPosition
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.
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
SPICE expressions need quoted versions of the netnames since KiCad allows '-' and '/' in netnames.
void rebuildSignalsList()
Rebuild the list of signals available from the netlist.
bool loadLegacyWorkbook(const wxString &aPath)
int m_splitterCursorsSashPosition
void ToggleSimSidePanel()
void UpdateMeasurement(int aRow)
Update a measurement in the measurements grid.
wxString getNoiseSource() const
std::vector< wxString > SimPlotVectors() const
unsigned int m_plotNumber
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.
int m_splitterLeftRightSashPosition
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.
std::vector< wxString > m_signals
SIM_TAB * GetCurrentSimTab() const
Return the currently opened plot panel (or NULL if there is none).
void SaveCursorToWorkbook(nlohmann::json &aTraceJs, TRACE *aTrace, int aCursorId)
void updateMeasurementsFromGrid()
bool LoadWorkbook(const wxString &aPath)
Load plot, signal, cursor, measurement, etc.
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 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.
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)
void OnFilterMouseMoved(wxMouseEvent &aEvent) override
void AddMeasurement(const wxString &aCmd)
Add a measurement to the measurements grid.
void onPlotChanging(wxAuiNotebookEvent &event) override
std::shared_ptr< SPICE_SIMULATOR > simulator() const
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()
SIM_TRACE_TYPE getXAxisType(SIM_TYPE aType) const
Return X axis for a given simulation type.
void OnPlotSettingsChanged()
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)
int m_splitterSignalsSashPosition
void OnSimReport(const wxString &aMsg)
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.
int m_splitterPlotAndConsoleSashPosition
SIMULATOR_FRAME * m_simulatorFrame
void ShowChangedLanguage()
void AddTuner(const SCH_SHEET_PATH &aSheetPath, SCH_SYMBOL *aSymbol)
Add a tuner for a symbol.
bool IsSimSidePanelShown()
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
void updateTrace(const wxString &aVectorName, int aTraceType, SIM_PLOT_TAB *aPlotTab, std::vector< double > *aDataX=nullptr, bool aClearData=false)
Update a trace in a particular SIM_PLOT_TAB.
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.
bool LoadSimulator(const wxString &aSimCommand, unsigned aSimOptions)
Check and load the current netlist into the simulator.
std::shared_ptr< SPICE_CIRCUIT_MODEL > GetCircuitModel() const
SIM_TYPE GetCurrentSimType() const
void OnModify() override
Must be called after a model change in order to set the "modify" flag and do other frame-specific pro...
int GetCurrentOptions() const
std::shared_ptr< SPICE_SIMULATOR > GetSimulator() const
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, const std::vector< SCH_PIN * > &aPins, REPORTER &aReporter)
void SetFilesStack(std::vector< EMBEDDED_FILES * > aFilesStack)
virtual const PARAM * GetTunerParam() const
const SPICE_GENERATOR & SpiceGenerator() const
void WriteFields(std::vector< SCH_FIELD > &aFields) const
void SetParamValue(int aParamIndex, const std::string &aValue, SIM_VALUE::NOTATION aNotation=SIM_VALUE::NOTATION::SI)
static void FillDefaultColorList(bool aWhiteBg)
Fills m_colorList by a default set of colors.
bool DeleteTrace(const wxString &aVectorName, int aTraceType)
wxString GetLabelY1() const
mpWindow * GetPlotWin() const
void ShowGrid(bool aEnable)
wxString GetUnitsY2() const
void SetY2Scale(bool aLock, double aMin, double aMax)
TRACE * GetTrace(const wxString &aVecName, int aType) const
wxString GetLabelX() const
const std::map< wxString, TRACE * > & GetTraces() const
wxString GetLabelY3() const
void SetY1Scale(bool aLock, double aMin, double aMax)
void SetY3Scale(bool aLock, double aMin, double aMax)
std::vector< std::pair< wxString, wxString > > & Measurements()
void UpdateTraceStyle(TRACE *trace)
Update plot colors.
void SetLegendPosition(const wxPoint &aPosition)
void ResetScales(bool aIncludeX)
Update trace line style.
void ShowLegend(bool aEnable)
wxString GetLabelY2() const
void SetTraceData(TRACE *aTrace, std::vector< double > &aX, std::vector< double > &aY, int aSweepCount, size_t aSweepSize)
void EnableCursor(TRACE *aTrace, int aCursorId, const wxString &aSignalName)
wxString GetUnitsX() const
void EnsureThirdYAxisExists()
TRACE * GetOrAddTrace(const wxString &aVectorName, int aType)
void SetDottedSecondary(bool aEnable)
Draw secondary signal traces (current or phase) with dotted lines.
void ApplyPreferences(const SIM_PREFERENCES &aPrefs) override
wxString GetUnitsY1() const
void DisableCursor(TRACE *aTrace, int aCursorId)
Reset scale ranges to fit the current traces.
wxString GetUnitsY3() const
int GetSimOptions() const
SIM_TYPE GetSimType() const
const wxString & GetSimCommand() const
static bool IsPlottable(SIM_TYPE aSimType)
void SetSimOptions(int aOptions)
wxString GetLastSchTextSimCommand() const
void SetSpicePlotName(const wxString &aPlotName)
static std::string ToSpice(const std::string &aString)
Special netlist exporter flavor that allows one to override simulation commands.
static SIM_TYPE CommandToSimType(const wxString &aCmd)
Return simulation type basing on a simulation command directive.
virtual std::string TunerCommand(const SPICE_ITEM &aItem, double aValue) const
static wxString TypeToName(SIM_TYPE aType, bool aShortName)
Return a string with simulation name based on enum.
Helper class to recognize Spice formatted values.
wxString ToString() const
Return string value as when converting double to string (e.g.
wxString ToSpiceString() const
Return string value in Spice format (e.g.
~SUPPRESS_GRID_CELL_EVENTS()
SUPPRESS_GRID_CELL_EVENTS(SIMULATOR_FRAME_UI *aFrame)
SIMULATOR_FRAME_UI * m_frame
void SetTraceColour(const wxColour &aColour)
bool HasCursor(int aCursorId)
CURSOR * GetCursor(int aCursorId)
Custom widget to handle quick component values modification and simulation on the fly.
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
A wrapper for reporting to a wxString object.
bool HasMessage() const override
Returns true if the reporter client is non-empty.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
const wxString & GetMessages() const
A KICAD version of wxTextEntryDialog which supports the various improvements/work-arounds from DIALOG...
wxString GetValue() const
const wxString & GetName() const
Get layer name.
const wxPen & GetPen() const
Get pen set for this layer.
Canvas for plotting mpLayer implementations.
int GetMarginLeft() const
void SetMargins(int top, int right, int bottom, int left)
Set window margins, creating a blank area where some kinds of layers cannot draw.
void UpdateAll()
Refresh display.
int GetMarginRight() const
int GetMarginBottom() const
bool AddLayer(mpLayer *layer, bool refreshDisplay=true)
Add a plot layer to the canvas.
void Fit() override
Set view to fit global bounding box of all plot layers and refresh display.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
Abstract pattern-matching tool and implementations.
@ GRIDTRICKS_FIRST_CLIENT_ID
static const std::string WorkbookFileExtension
KICOMMON_API wxFont GetStatusFont(wxWindow *aWindow)
SIM_TYPE
< Possible simulation types
void sortSignals(std::vector< wxString > &signals)
wxString vectorNameFromSignalId(int aUserDefinedSignalId)
MEASUREMENTS_GIRD_COLUMNS
SIM_TRACE_TYPE operator|(SIM_TRACE_TYPE aFirst, SIM_TRACE_TYPE aSecond)
@ MYID_DELETE_MEASUREMENT
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
int measurements_panel_height
SIM_PREFERENCES preferences
Contains preferences pertaining to the simulator.
Definition of file extensions used in Kicad.