//************************************************************************************************** // PnlNgSpiceAC.cpp * // ------------------ * // Started : 2004-08-04 * // Last Update : 2016-10-01 * // Copyright : (C) 2004-2016 MSWaters * //************************************************************************************************** //************************************************************************************************** // * // This program is free software; you can redistribute it and/or modify it under the * // terms of the GNU General Public License as published by the Free Software Foundation; * // either version 3 of the License, or (at your option) any later version. * // * //************************************************************************************************** #include "PnlNgSpiceAC.hpp" //************************************************************************************************** // Implement an event table. wxBEGIN_EVENT_TABLE( PnlNgSpiceAC, PnlAnaBase ) EVT_RADIOBOX( PnlAnaBase::ID_RBX_SCALE , PnlNgSpiceAC::OnScale ) EVT_CHOICE ( PnlAnaBase::ID_CHO_SRCNAME, PnlNgSpiceAC::OnSrcName ) wxEND_EVENT_TABLE( ) //************************************************************************************************** // Constructor. PnlNgSpiceAC::PnlNgSpiceAC( wxWindow * poWin ) : PnlAnaBase( poWin ) { bSetAnalysType( eCMD_AC ); Create( ); // Create the analysis panel bClear( ); // Clear all object attributes } //************************************************************************************************** // Destructor. PnlNgSpiceAC::~PnlNgSpiceAC( ) { } //************************************************************************************************** // Create the display objects. void PnlNgSpiceAC::Create( void ) { PnlAnaBase::CreateBase( ); // Create the base controls PnlAnaBase::CreateScale( ); // Create the scale controls PnlAnaBase::CreateCpxPrt( ); // Create the simulation parameter complex part check boxes PnlAnaBase::CreateSigSrc( ); // Create input signal source controls PnlAnaBase::CreateTemp( ); // Create the analysis temperature controls PnlAnaBase::DoLayout( ); // Layout the panel's GUI objects // Set the frequency sweep parameter labels m_oSbxSwpPars.SetLabel( wxT(" AC Sweep ") ); m_oPnlStart .bSetName( wxT("Start Frequency") ); m_oPnlStop .bSetName( wxT("Stop Frequency") ); // Set sweep parameter spin control parameters and units m_oPnlStart.bSetUnitsType( eUNITS_FREQ ); m_oPnlStop .bSetUnitsType( eUNITS_FREQ ); m_oPnlStep .bSetValueType( eVALUE_INT ); m_oPnlStep .bShowUnits( PnlValue::eSHOW_LBL ); // Disable the scale option NG-Spice doesn't support m_oRbxSweep.Enable( eSCALE_LOG, false ); // Disable the checkboxes for the parameters NG-Spice cannot calculate m_oCbxCurrent.Disable( ); m_oCbxPower .Disable( ); m_oCbxResist .Disable( ); } //************************************************************************************************** // Initialize the step scale. void PnlNgSpiceAC::InitScale( void ) { switch( m_oRbxSweep.GetSelection( ) ) { case eSCALE_LIN : m_oPnlStep.bSetName( wxT("Steps in Total") ); m_oPnlStep.bSetSpnRange( 1, 100000 ); m_oPnlStep.bSetSpnIncSz( 1, 10000 ); m_oPnlStep.bSetDefValue( 10 ); break; case eSCALE_DEC : m_oPnlStep.bSetName( wxT("Steps / Decade") ); m_oPnlStep.bSetSpnRange( 1, 10000 ); m_oPnlStep.bSetSpnIncSz( 1, 1000 ); m_oPnlStep.bSetDefValue( 10 ); break; case eSCALE_OCT : m_oPnlStep.bSetName( wxT("Steps / Octave") ); m_oPnlStep.bSetSpnRange( 1, 10000 ); m_oPnlStep.bSetSpnIncSz( 1, 1000 ); m_oPnlStep.bSetDefValue( 10 ); break; default : break; } } //************************************************************************************************** // Set the state of the step scale radio box. // // Argument List : // eScale - The enumerated scale specifier // // Return Values : // Success - true // Failure - false bool PnlNgSpiceAC::bSetScale( eTypeScale eScale ) { if( eScale == eSCALE_NONE ) return( false ); #if wxCHECK_VERSION( 2,8,0 ) if( m_oRbxSweep.GetCount( ) < (uint) eScale + 1 ) return( false ); #else if( m_oRbxSweep.GetCount( ) < (int) eScale + 1 ) return( false ); #endif m_oRbxSweep.SetSelection( (int) eScale ); InitScale( ); return( true ); } //************************************************************************************************** // Clear the object attributes. // // Return Values : // true - Success // false - Failure bool PnlNgSpiceAC::bClear( void ) { // Clear the base class PnlAnaBase::bClear( ); // Set the sweep parameters to their defaults m_oPnlStart.bSetValue( (float) 1.0 ); m_oPnlStop .bSetValue( (float) 100.0 ); m_oPnlStep .bSetValue( (float) 10.0 ); m_oPnlStart.bSetUnits( wxT("kHz") ); m_oPnlStop .bSetUnits( wxT("kHz") ); // Set default scale value bSetScale( eSCALE_DEC ); // Set input source default values m_oChoSrcName.Clear( ); m_oChoSrcName.Append( wxT("None") ); m_oChoSrcName.SetSelection( 0 ); m_oPnlSrcLvl.bSetValue( (float) 0.0 ); m_oPnlSrcLvl.bSetUnitsType( eUNITS_NONE ); // Set parameters check box default values m_oCbxVoltage.SetValue( true ); m_oCbxCurrent.SetValue( false ); m_oCbxPower .SetValue( false ); m_oCbxResist .SetValue( false ); // Set the complex part check box default values m_oCbxMag .SetValue( true ); m_oCbxPhase.SetValue( false ); m_oCbxReal .SetValue( false ); m_oCbxImag .SetValue( false ); m_oCbxMagDb.SetValue( true ); // Set default temperature value m_oPnlTemp.bSetValue( 27.0 ); return( true ); } //************************************************************************************************** // Load information from a simulation object. // // Argument List : // roSim - A simulation object // // Return Values : // true - Success // false - Failure bool PnlNgSpiceAC::bLoad( SimnNgSpice & roSimn ) { bool bRtn=true; // Load components into the source choice box PnlAnaBase::LoadSrcNames( roSimn.m_oaCpnts, wxT("VI") ); // Go no further if the AC command isn't valid if( ! roSimn.m_oCmdAC.bIsValid( ) ) return( false ); // Set the source component if( ! PnlAnaBase::bSetSrcCpnt( roSimn.m_oCpntSwpSrc ) ) bRtn = false; // Set the step scale (do this before setting the sweep step) m_oRbxSweep.SetSelection( roSimn.m_oCmdAC.m_eScale ); // Set the sweep values if( ! m_oPnlStart.bSetValue( roSimn.m_oCmdAC.m_osStart ) ) bRtn = false; if( ! m_oPnlStop .bSetValue( roSimn.m_oCmdAC.m_osStop ) ) bRtn = false; if( ! m_oPnlStep .bSetValue( roSimn.m_oCmdAC.m_osStep ) ) bRtn = false; // Set the complex parts to derive m_oCbxMag .SetValue( roSimn.m_oCmdPR.m_bCpxPts[ eCPXPT_MAG ] ); m_oCbxPhase.SetValue( roSimn.m_oCmdPR.m_bCpxPts[ eCPXPT_PHASE ] ); m_oCbxReal .SetValue( roSimn.m_oCmdPR.m_bCpxPts[ eCPXPT_REAL ] ); m_oCbxImag .SetValue( roSimn.m_oCmdPR.m_bCpxPts[ eCPXPT_IMAG ] ); m_oCbxMagDb.SetValue( roSimn.m_oCmdPR.m_bCpxPts[ eCPXPT_MAGDB ] ); // Set the analysis temperature if( ! m_oPnlTemp.bSetValue( roSimn.m_oCmdOPT.m_osTEMP ) ) bRtn = false; return( bRtn ); } //************************************************************************************************** // Save information to a simulation object. // // Argument List : // roSimn - A simulation object // // Return Values : // true - Success // false - Failure bool PnlNgSpiceAC::bSave( SimnNgSpice & roSimn ) { wxString os1; float f1; size_t sz1; bool b1; m_osErrMsg.Empty( ); // Set the analysis type roSimn.m_oCmdPR.bSetAnaType( eCMD_AC ); // Check the start frequency (can't set a frequency of zero so set one as // small as possible, 1.4e-45 is as small as I can go as a float but it will // be converted to a string in engineering units so use 1.0e-15 = 1.0f) CnvtType::bStrToFlt( roSimn.m_oCmdAC.m_osStart, &f1 ); if( f1 == 0.0 ) roSimn.m_oCmdAC.m_osStart = wxT("1.0e-15"); // Set the sweep values roSimn.m_oCmdAC.m_osStart = m_oPnlStart.rosGetValue( ); roSimn.m_oCmdAC.m_osStop = m_oPnlStop .rosGetValue( ); roSimn.m_oCmdAC.m_osStep = m_oPnlStep .rosGetValue( ); // Set the sweep scale roSimn.m_oCmdAC.m_eScale = (eTypeScale) m_oRbxSweep.GetSelection( ); // Set the sweep source component if( m_oChoSrcName.GetStringSelection( ) == wxT("None") ) SetErrMsg( wxT("No source component has been selected.") ); else if( m_oPnlSrcLvl.dfGetValue( ) == 0.0 ) SetErrMsg( wxT("Signal source component value of zero is not permitted.") ); else { os1 = m_oChoSrcName.GetStringSelection( ); roSimn.m_oCpntSwpSrc = roSimn.NetList::roGetCpnt( os1 ); os1 = wxT("AC ") + m_oPnlSrcLvl.rosGetValue( ); roSimn.m_oCpntSwpSrc.bSetValue( os1 ); } // Store the parameters to derive roSimn.m_oCmdPR.m_bParams[ ePARAM_VLT ] = m_oCbxVoltage.GetValue( ); roSimn.m_oCmdPR.m_bParams[ ePARAM_CUR ] = m_oCbxCurrent.GetValue( ); roSimn.m_oCmdPR.m_bParams[ ePARAM_PWR ] = m_oCbxPower .GetValue( ); roSimn.m_oCmdPR.m_bParams[ ePARAM_RES ] = m_oCbxResist .GetValue( ); // Store the complex parts of the parameters to derive roSimn.m_oCmdPR.m_bCpxPts[ eCPXPT_MAG ] = m_oCbxMag .GetValue( ); roSimn.m_oCmdPR.m_bCpxPts[ eCPXPT_PHASE ] = m_oCbxPhase.GetValue( ); roSimn.m_oCmdPR.m_bCpxPts[ eCPXPT_REAL ] = m_oCbxReal .GetValue( ); roSimn.m_oCmdPR.m_bCpxPts[ eCPXPT_IMAG ] = m_oCbxImag .GetValue( ); roSimn.m_oCmdPR.m_bCpxPts[ eCPXPT_MAGDB ] = m_oCbxMagDb.GetValue( ); // Create the command strings roSimn.m_oCmdAC.bFormat( ); roSimn.m_oCmdPR.bFormat( ); // Check for errors if( ! roSimn.m_oCmdAC.bIsValid( ) ) SetErrMsg( roSimn.m_oCmdAC.rosGetErrMsg( ) ); if( ! roSimn.m_oCmdPR.bIsValid( ) ) SetErrMsg( roSimn.m_oCmdPR.rosGetErrMsg( ) ); for( sz1=eCPXPT_MAG, b1=false; sz1<=eCPXPT_IMAG; sz1++ ) if( roSimn.m_oCmdPR.m_bCpxPts[ sz1 ] ) b1 = true; if( ! b1 ) SetErrMsg( wxT("No complex parts have been selected.") ); return( bIsOk( ) ); } //************************************************************************************************** // Event Handlers * //************************************************************************************************** // Step scale radio box event handler. // // Argument List : // roEvtCmd - An object holding information about the event void PnlNgSpiceAC::OnScale( wxCommandEvent & roEvtCmd ) { InitScale( ); } //************************************************************************************************** // Source component choice box event handler. // // Argument List : // roEvtCmd - An object holding information about the event void PnlNgSpiceAC::OnSrcName( wxCommandEvent & roEvtCmd ) { wxString os1; // Execute the base class event handler first PnlAnaBase::OnSrcName( roEvtCmd ); if( m_oChoSrcName.GetStringSelection( ) != wxT("None") ) { // Set the units type os1 = m_oChoSrcName.GetStringSelection( ); m_oPnlSrcLvl.bSetUnitsType( Component::eGetUnitsType( os1 ) ); // Set the source value if( m_oPnlSrcLvl.dfGetValue( ) == 0.0 ) m_oPnlSrcLvl.bSetValue( (double) 1.0 ); } else { m_oPnlSrcLvl.bSetUnitsType( eUNITS_NONE ); m_oPnlSrcLvl.bSetValue( (double) 0.0 ); } } //**************************************************************************************************